Say I had an object created dynamically like so...
var indexes = {};
for (var i = 0; i < specchar.length; i++) {
indexes[specchar[i]] = str.indexOf(specchar[i]);
}
How would I find the property with the highest value?
The most efficient way is to keep track of the max value as your object is being dynamically created like so:
var indexes = {};
var maxVal = str.indexOf(specchar[0]); // contains largest value
var maxKey = ''; // contains key corresponding to largest value
for (var i = 0; i < specchar.length; i++) {
var val = str.indexOf(specchar[i]);
if (val > maxVal) {
maxVal = val;
maxKey = specchar[i];
}
indexes[specchar[i]] = val;
}
You also can find max value using Math.max.apply. If you work with object then first need get values and push into array.
var fixtures = {};
for (var i = 0; i < Math.random() * 20 + 5; i++) {
fixtures[i] = Math.random() * 20 - 10;
}
// Procceed object and push values to array
var values = [],
maxValue = 0;
for (var key in fixtures) {
values.push(fixtures[key]);
}
// Find max value
maxValue = Math.max.apply(Math.max, values);
// Print results to console
console.dir(values);
console.log(maxValue);
But if you get an array values and you want find max value from, you can just call Math.max.apply(Math.max, values) an it returns max value.
You can also use a for-in.
var indexes = {};
var maxIndexVal = str.indexOf(specchar[0]); // this will hold the maximum value found
for(var index in specchar){
var foundIndex = str.indexOf(specchar[index]); // returns the index if found
// compare values; add max values to indexes
if(foundIndex > maxIndexVal) {
maxIndexVal = foundIndex;
indexes[specchar[maxIndexVal]] = maxIndexVal;
}
}
Related
I have this array of objects to count element frequency in another array using for loop which prints correct output.
counts = {};
counter = 0;
counter_array = [50,50,0,200]; //this is just for example, this array is filled dynamically
for (var x = 0, y = counter_array.length; x < y; x++) {
counts[counter_array[x]] = (counts[counter_array[x]] || 0) + 1;
}
console.log('FREQUENCY: ',counts); //outputs FREQUENCY: {50:2, 0:1, 200:1}
There is another array of arrays:
holder_text_array = [["a",50,0],["b",0,0]]; //example of dynamically filled array
var p = "a";
var i = 0;
while(i < holder_text_array.length){
if (holder_text_array[i][0]==p) {
var s = counts[holder_text_array[i][1]];
console.log('Element: ', holder_text_array[i][1]); //prints 50 for i = 0
console.log('frequency: ',counts[s]); //prints undefined
counter = counts[s];
}
i++;
}
The array of arrays "holder_text_array" consists of elements whose frequency I need to get in the while loop. Can someone tell me where am I wrong?
The frequency is stored in s not in counts[s]
You're logging counts[s] where var s = counts[holder_text_array[i][1]];
You've already got the element from counts in s. Just log the value of s
Apart from that the function works!
counts = {};
counter = 0;
counter_array = [50,50,0,200]; //this is just for example, this array is filled dynamically
for (var x = 0, y = counter_array.length; x < y; x++) {
counts[counter_array[x]] = (counts[counter_array[x]] || 0) + 1;
}
console.log('FREQUENCY: ',counts); //outputs FREQUENCY: {50:2, 0:1, 200:1}
holder_text_array = [["a",50,0],["b",0,0]]; //example of dynamically filled array
var p = "a";
var i = 0;
while(i < holder_text_array.length){
if (holder_text_array[i][0]==p) {
var s = counts[holder_text_array[i][1]];
console.log('Element: ', holder_text_array[i][1]); //prints 50 for i = 0
console.log('frequency: ', s); // CHANGED THIS TO JUST `s`
counter = counts[s];
}
i++;
}
You could take a recursive approach and call the count function again for (nested) arrays with the same counts object.
The result contains the counts of each element.
function getCounts(array, counts = {}) {
for (let i = 0; i < array.length; i++) {
const value = array[i];
if (Array.isArray(value)) {
getCounts(value, counts);
continue;
}
if (!counts[value]) counts[value] = 0;
counts[value]++;
}
return counts;
}
console.log(getCounts([["a", 50, 0], ["b", 0, 0]]));
I figured out the problem. Issue is in initialization.
I changed the following:
var s = counts[holder_text_array[i][1]];
counter = counts[s];
It works this way:
var s = holder_text_array[i][1];
counter = counts[s];
Let's say that I'm doing this because of my homework. I would like to develop some kind of schedule for the week to come (array of 6-7 elements - output result). But I have one problem. I need to figure it out how one element be positioned in the array and also his frequency must be exactly what user input is. Elements must be positioned at different index in the array.
I'm having that kind of input from user (just an example);
var arrayOfElements = ["el1","el2","el3"];
var el1Frequency = 3;
var el2Frequency = 2;
var el3Frequency = 1;
//output array of schedule (this is just an example)
var finaloutPutArray = ["el1","el2","el3","el1","el2","el1"];
Index of elements el1 is 0, 3 and 5, basically, I don't want elements to be repeated like this;
["el1","el1","el2","el3"...];
["el2","el1","el1","el3"];
Can you please give me some ideas on how to solve this problem.
I started like this;
var finalSchedule = [];
var totalDaysPerWeek = 6;
for(var i =0; i < totalDaysPerWeek; i++) {
...
}
This is one pattern, check my working snippet:
var arrayOfElements = ["el1","el2","el3"];
var obj = { el1: 3,
el2: 2,
el3: 1};
// First determine the max recurring of an element, this will be the number of cycles fo your loop
// Check key values
var arr = Object.keys(obj).map(function ( key ) { return obj[key]; });
// Get max value
var max = Math.max.apply( null, arr );
var finalArray = [];
// Iterate from 0 to max val
for(i = 0; i < max; i += 1){
// Iterate on array of elements
for(k = 0; k < arrayOfElements.length; k += 1) {
// If config of recurring
if( obj[arrayOfElements[k]] >= i+1 ) {
// Push into array
finalArray.push(arrayOfElements[k]);
}
}
}
console.log(finalArray);
I'm trying to figure out how to get cumulative values from a data table that a user enters values in. I've stored all of the data into an array representing the raw data, and I am trying to increment an array which is a copy of the array representing the raw data in order to obtain the cumulative data for the graph. I am trying to do this by incrementing each value object of the array to the values of each index of the raw data array up to the current index. I'm doing this through a loop, but it doesn't seem to be working. My code for the function is here:
function generateChartData() {
var rawData = [];
var chartData = [];
jQuery('.data-row').each(function () {
var date = jQuery(this).find('.data-category').val();
var value = jQuery(this).find('.data-value').val();
var value2 = jQuery(this).find('.data-value2').val();
if (date != '') {
rawData.push({
date: date,
value: value,
value2: value2
});
}
});
for (var i = 0; i < rawData.length; i++)
{
chartData[date][i] = rawData[date][i];
for(var j = i; j >= 0; j--)
{
chartData[i][value]+=rawData[j][value];
chartData[i][value]+=rawData[j][value2];
}
}
return chartData;
}
Here is the jsfiddle
You're not properly accessing array and object elements. And you can just use a simple variable to hold the running total.
var valueSum = 0;
var value2Sum = 0;
for (var i = 0; i < rawData.length; i++) {
rd = rawData[i];
valueSum += rd.value;
value2Sum += rd.value2;
chartData.push({
date: rd.date,
value: valueSum,
value2: value2Sum
});
}
I have a nice riddle that I would like to see solved. There might be a better way of doing this and i am open for idea's.
I am trying to write an undo function for a canvas drawing app.
I have the following object, within it an array with their own objects with three properties.
var allDamages= {};
allDamages['scratch'] = [];
allDamages['scratch'].push({"x":4,"y":6,"index":1});
allDamages['scratch'].push({"x":3,"y":3,"index":2});
allDamages['scratch'].push({"x":9,"y":9,"index":3});
allDamages['scratch'].push({"x":19,"y":39,"index":4});
allDamages['dent'] = [];
allDamages['dent'].push({"x":59,"y":69,"index":5});
allDamages['dent'].push({"x":59,"y":69,"index":9});
allDamages['dent'].push({"x":39,"y":19,"index":6});
allDamages['rip'] = [];
allDamages['rip'].push({"x":20,"y":22,"index":7});
allDamages['rip'].push({"x":100,"y":56,"index":8});
I want to remove the last entry from this array. I want to do this by the property 'index'.
So I need to somehow find the entry which has the highest value of the property 'index' and then remove it from the array. What is the best way in doing this?
Greetings,
Robert
allDamages.scratch.length -1 returns the last index for that array.
Edit:
allDamages.scratch.slice(-1).pop() returns the last array item.
And if you just want to remove the last item in your array you should (like Givi said) use the pop() method on a sorted array like so:
allDamages['scratch'].pop()
Edit2:
Because the question wasn't clear for me. This is my final shot at the problem.
var allDamagesInOneArray = [];
for(array in allDamages){
allDamagesInOneArray.concat(array);//Assuming every key is an array
}
allDamagesInOneArray.sort(function(a,b){
return a.index - b.index;
});
var lastObj = allDamagesInOneArray.slice(-1).pop(); //element with latest index
I think you should create an object that save three your properties. After that you create a stack for undo. Like this:
function yourObject(x,y,index){
this.x = x; this.y = y; this.index = index;
}
var yourStack = new Array();
yourStack.push(new yourObject(4, 6, 1));
If the highest index in an array is always the last element of the array:
allDamages.scratch = allDamages.scratch.slice(0, allDamages.scratch.length - 1);
This removes the last element of the array
If index is not incrementing or if you always want to remove the latest index, no matter in which of the damages arrays it is (as I'd guess) you can use this function:
var undo = function(input){
var max= 0;
var undoType = "";
var undoIndex = 0;
for( var type in input ) {
// type: string
var locations = input[type];
// locations: array
// find the location of the heighest index property.
for( var i = 0; i < locations.length; i++ ) {
if( locations[i]["index"] > max) {
max = locations[i]["index"] ;
undoType = type;
undoIndex = index;
}
}
}
var output = input[type].splice(undoIndex, 1);
return output;
}
This should remove the element with the largest "index" property from your damage array.
First off, store a counter for highest index property found in the objects, and the index of that object within the scratch array.
var highestIndex = -Infinity;
var indexInArray
Then if you're using jQuery:
$.each( allDamages.scratch, function highestIndex( index, object ){
if( object.index > highestIndex ){
highestIndex = object.index;
indexInArray = index;
}
} );
Or, if not:
for( var indexCounter = 0, indexCounter < allDamages.scratch, indexCounter++ ){
if( allDamanges.scratch[ indexCounter ].index > highestIndex ){
highestIndex = allDamages.scratch[ indexCounter ].index;
indexInArray = indexCounter;
}
};
Try:
var allDamages= {};
allDamages['scratch'] = [];
allDamages['scratch'].push({"x":4,"y":6,"index":1});
allDamages['scratch'].push({"x":3,"y":3,"index":2});
allDamages['scratch'].push({"x":9,"y":9,"index":3});
allDamages['scratch'].push({"x":19,"y":39,"index":4});
allDamages['dent'] = [];
allDamages['dent'].push({"x":59,"y":69,"index":5});
allDamages['dent'].push({"x":59,"y":69,"index":9});
allDamages['dent'].push({"x":39,"y":19,"index":6});
allDamages['rip'] = [];
allDamages['rip'].push({"x":20,"y":22,"index":7});
allDamages['rip'].push({"x":100,"y":56,"index":8});
var index;
var cnt = 0;
var val;
$.each(allDamages,function(k,v){
if(cnt == 0){
index = highest(v); //get highest value from each object of allDamages
val = k;
}
else{
if(highest(v) > index){
index = highest(v);
val = k;
}
}
cnt++;
});
console.log("highest : "+index+": "+val);
var len = allDamages[val].length;
for(var i=0;i<len;i++){
if(allDamages[val][i].index == index){
allDamages[val].splice(i,1); //remove object having highest value
break;
}
}
console.log(allDamages);
function highest(ary) {
var high = ary[0].index;
var len = ary.length;
if(len > 0){
for(var i=0;i<len;i++){
if(ary[i].index > high){
high = ary[i].index;
}
}
}
return high;
}
DEMO here.
I've simplified my array to:
allDamages.push({"x":39,"y":19,"index":6,"type":'dent'});
That way i can use .pop() function in a normal way.
Thank you all for the quick response!!!
I have two arrays which are created from the inputs of a user like so:
var impArray = [];
$('[id^=imp]').on('change', function(){
var value = $(this).val();
var name = ($(this).attr('name').replace('imp-',''))
impArray[name] = value;
console.log(impArray);
})
var assessArray= [];
$('[id^=assess]').on('change', function(){
var value = $(this).val();
var name = ($(this).attr('name').replace('assess-',''))
assessArray[name] = value;
console.log(assessArray);
})
These create arrays like
assessAray
1-1: 10
1-2: 15
1-3: 9
impArray
1-1: 6
1-2: 14
1-3: 2
I then need to do a simple calculation with the matching keys like:
$('#comp-1-1').val(impArray['1-1'] / assessArray['1-1'] * 100);
Obviously I can't do this with every single one, so,
Question: How can I loop through the arrays and compare them based on keys then do something with their values?
Technically, you are working with JavaScript objects, not arrays. Your variable declarations should actually be:
var impArray = {};
var assessArray = {};
Once you have the correct variable declarations, you can use jQuery.each to iterate through keys (not indexes):
$.each(impArray, function(key, value){
$('#comp-'+key).val(assessArray[key]/value*100);
});
Try using $.each(), like:
$.each(impArray, function(i, v){
$('#comp-'+i).val(v/assessArray[i]*100);
});
Does this help you?
$.each(impArray, function(index, value){
var result = assessArray[index] / value * 100;
$('#comp-1-'+index).val(result);
});
If both arrays will always be the same length and have the object property at the same index, this should work:
http://jsfiddle.net/9DBuD/
assessArray = [{'1-1':'10'},{'1-2':'15'},{'1-3':'9'}];
impArray = [{'1-1':'6'},{'1-2':'14'},{'1-3':'2'}];
for(var i=0;i<assessArray.length;i++){
for(var prop in assessArray[i]){
for(var property in impArray[i]){
if(prop == property){
$('#comp-'+prop).val(impArray[i][property]/assessArray[i][prop]*100)
}
}
}
}
Edit
This modified fiddle and code should produce the same results even if the array indexes and sizes do not match:
http://jsfiddle.net/9DBuD/1/
Array.prototype.indexOfProp = function (property) {
for (var i = 0, len = this.length; i < len; i++) {
if (this[i][property]!=undefined) return i;
}
return -1;
}
assessArray = [{'1-2':'15'},{'1-3':'9'},{'1-1':'10'},{'1-4':'10'}];
impArray = [{'1-1':'6'},{'1-3':'2'},{'1-2':'14'}];
for(var i=0;i<assessArray.length;i++){
for(var prop in assessArray[i]){
var index = impArray.indexOfProp(prop)
if(index!=-1){
$('#comp-'+prop).val(impArray[index][prop]/assessArray[i][prop]*100)
}
}
}