Basically I have about 36 variables that are named t0, t1, t3 ... and so on, each variable is initiated with the value 0, and depending on actions they get incremented by 1.
I want a way to be able to list the top ten highest valued variables ideally by putting them in an array like Var topTen = [t33,t31,t2].
Why don't you use an object to store the information - instead of 36 variables have just one object with 36 properties. Then you can loop through the values, add them to an array and grab the set of numbers you need:
var obj = {
t1: 1,
t2: 33,
t3: 10,
t4: 9,
t5: 45,
t6: 101,
...
}
// create an array
var arr = [];
// loop through the object and add values to the array
for (var p in obj) {
arr.push(obj[p]);
}
// sort the array, largest numbers to lowest
arr.sort(function(a,b){return b - a});
// grab the first 10 numbers
var firstTen = arr.slice(0, 9);
This will return an array - just loop through it to list the values one by one.
DEMO
Should try this method :
var myarray=["t14", "t53", "t1"]
myarray.sort();
myarray.reverse();
var final = myarray.slice(0,10);
//SHOULD GIVE YOU
// ["t53", "t14", "t1"]
Then you can extract the ten first value.
UPDATE --> JSFiddle
res = [{k:"t1",v:t1},{k:"t2",v:t2},...,{k:"t36",v:t36}].sort(
function(a,b){
return b.v-a.v
}).map(function(x){return x.k}).slice(0,9)
btw. you can create the array dynamically if the variables are represented as object properties...
if you need the values, then return x.v instead of x.k
First put the variables in an array:
var ts = [t0, t1, ...];
You can then get the top 10 like this:
var topTen = ts.sort().slice(-10).reverse();
Ideally you want store all your values in an array in the first place.
Sort your array after that slice first 10 elements.
arr.sort(function (a,b) {
return a - b;
});
var result = arr.slice(0,10);
Related
I came across this code that is used to keep both forward and reverse reference in an array:
var arr = [];
arr[arr['A'] = 0] = 'A';
arr[arr['B'] = 1] = 'B';
// On node interpreter
arr // [ 'A', 'B', A: 0, B: 1 ]
arr["A"] // 0
arr["B"] // 1
arr[0] // 'A'
arr[1] // 'B'
arr[2] // 'undefined'
arr.length // 2
The A: 0, B: 1 members get pushed to the end of the array.
What are these members and what happened in the process so that .length property recorded 2 instead of 4?
Storing a value with a string key into an array does not actually modify the array. It only adds a dynamic field to the Array object, unlike storing with a numeric index, which actually pushes a value into the array.. Array.length only reflects the number of elements in the array, as managed by the array, but not the number of dynamic fields in the array.
var arr = [];
arr["A"] = 2;
Here you are adding a property to the array object which does not reflect over the number of elements in the array.In javascript, elements of array are always stored using indices.
Array.length always returns the number of elements stored in the array.
As I know, it is possible to push more data into an array. Fe, I have an array:
G = [12, 34, 5].
Right now, I can access the nth element like this:
G[n]
I'd now like to push new data in it with a label, so I want the array to look like
G = [12, 34, 5, label:567856, other: Infinity]
where I can get 567856 by calling
G["label"] //(or Infinity by calling G["other"]). How can I achieve this?
I've found
G[i].push({
label:567856,
other: Infinity
})
but this way it adds it as a whole new element, and I'm only able to call G[4]["other"], instead of G["other"]. How can I add the element as I've described?
Thank you!
To add onto Andriy's answer, you need to use Javascript Objects rather than arrays. An object can have indices with custom names. For example, given
var newObj = {"hello": "world", "value":1, "inf": Infinity}
you can do
newObj['hello'] // "world"
newObj['value'] // 1
The problem with
G[i].push({
label:567856,
other: Infinity
})
is that you are pushing an object with 2 attributes, not pushing 2 objects, that's why you need to use G[4]["other"]
See running JSFiddle example.
G["other"] = "something";
With this you will keep the original array, and now have the attribute other, but it is not in [12, 34, 5]
Whit this one you can add an object to the array:
G.push({other: 123})
console.log(G);//[12, 34, 5, object]
console.log(G[3].other);//123
The problem with
G[i].push({
label:567856,
other: Infinity
})
is that you are pushing an object with 2 attributes, not pushing 2 objects, that's why you need to use G[4]["other"]
Arrays in JavaScript are a type of object. As such, they can contain properties:
G.label = 567856;
G.other = Infinity;
The advantage of arrays over other objects is that their indexed elements are ordered.
If you'd like the fourth and fifth elements in the array to be 567856 and Infinity and you want to be able to refer to those values with G.label and G.other, you can do so as follows:
var G = [12, 34, 5];
G.push(G.label = 567856); //same as G.label = 567856; G.push(G.label);
G.push(G.other = Infinity);
You can still iterate through the array using a loop:
var G = [12, 34, 5];
G.push(G.label = 567856);
G.push(G.other = Infinity);
G.forEach(function(val) {
console.log(val); // 12 ... 34 ... 5 ... 567856 ... Infinity
});
console.log(G.label); //567856
console.log(G.other); //Infinity
Note that this does create duplicates. If you change G.label or G.other afterwards, those changes will not be reflected in the fourth and fifth elements of the array.
However, you can overcome that by creating setters on G.label and G.other using Object.defineProperty():
var G = [12, 34, 5];
G.push(G.label = 567856);
G.push(G.other = Infinity);
G.forEach(function(val) {
console.log(val); // 12 ... 34 ... 5 ... 567856 ... Infinity
});
console.log(G.label); //567856
console.log(G.other); //Infinity
Object.defineProperty(G, 'label', {
set: function(x) {
this[3] = x;
}
});
Object.defineProperty(G, 'other', {
set: function(x) {
this[4] = x;
}
})
G.label = 99999;
G.other = 11111;
G.forEach(function(val) {
console.log(val); // 12 ... 34 ... 5 ... 99999 ... 11111
});
Arrays isn't designed to suit your case.
See Array element accessing flow from ECMAScript 262, 5.1 15.4
Array objects give special treatment to a certain class of property
names. A property name P (in the form of a String value) is an array
index if and only if ToString(ToUint32(P)) is equal to P and
ToUint32(P) is not equal to 2^32−1.
So you simply cannot access Array element by alphabetical name because that key won't be parsed to integer by ToUint32.
You can add object to array and store it's index after pushing into array ( Array.prototype.push would return you size of your array):
var G = [1,3,4];
var labelIndex = G.push({'label': 123}) - 1;
console.log(G[labelIndex]["label"]);
Actually that's solution would suite case when you have two or more objects inside your array with same property.
Suggestion below not recommended!
However, you can use code below to define your G Array properties, but it's not value of property of item from your array, it's array property:
G.other = Infinity;
G.label = 567856;
// Access newly created properties
console.log(G["other"]);
console.log(G["label"]);
Good Luck !
function largestInEach(arr) {
var resultArray = [],
highestValue = 0;
for (var i = 0; i < arr.length; i++) {
highestValue = arr[i].reduce(function(a, b){
return a >= b ? a : b;
});
resultArray.push(highestValue);
}
return resultArray;
}
Can someone please explain this code.
The rest of the code is very clear to me, but I have difficulty understanding the reduce function and its application.
I agree with most of the other comments that you should search more and do self learning.
However, I know it is sometimes hard to find the exact info on how things work. So ill explain this to you.
Now coming to your code.
https://jsfiddle.net/Peripona/ppd4L9Lz/
It contains an array of arrays where you at the end create a resulted array with highest or lowest value elements from all the sub arrays.
like you got
var arry = [[1,2,3],[2,3,4],[20,-2,3]]
talking in layman terms...
you got one array if you sort or reduce an array of integers, it might not always generate what you
say for example if you got this data
var ar = [1,3,34,11,0,13,7,17,-2,20,-21]
and if you do normal ar.sort() to get the sorted values
you would expect something like this... as output
" [-21, -2, 0, 1, 3, 7, 11, 13, 17, 20, 34] "
but on the contrary you would get the output like this..
" [-2, -21, 0, 1, 11, 13, 17, 20, 3, 34, 7] "
Now you wonder... why this strange behavior and how does it matter anyhow to my Question..
It Does matter..
Cuz this is what you need to do to get the right output..
The way sort function is written has to work for for String and other types as well. so they convert data into other formats when doing comparison on sort.
So all in all if you pass a function inside and specify that you need the in ascending order that is a-b..
Descending order that is b-a..
ar.sort(function(a,b){return a-b;})
Now coming to another part that is Reduce this function takes a function argument and get you the highest or the lowest value from the array.
therefore if you do..
ar.reduce(function(a,b){return a>=b ? b : a})
will give you -21 as the output..
and if you do
ar.reduce(function(a,b){return a>=b ? a : b})
It will give you : 34
So this function will take multidimensional arrays where each array contains some digits and this function will get you the highest from all those arrays..
I hope this Explains everything.
Reduce function allows you to go through each item in an array, where you will be able to see previous array value, and current array value, in your case:
a = previous value,
b = current value,
-(not in there)-
i = index,
currArray = the array you are working with.
and in your code you are comparing and returning if your previous value is greater than or equal to current value.
a >= b ? a : b;
Conditional (ternary) Operator which is (condition ? do this : or this ) -> Think of it like a if statement
If(a >= b){
return a
}else{
return b
}
see Conditional (ternary) Operator
Also your 'arr' could be multi dimensional array. forexample Trying the following code on http://plnkr.co/edit/?p=preview
hit f12 for developer tools and look at console for results.
var arr = [[1,2],[4,3],[5,23,52]];
var resultArray = [],
var highestValue;
for (var i = 0; i < arr.length; i++) {
highestValue = arr[i].reduce(function(a, b){
return a >= b ? a : b;
});
resultArray.push(highestValue);
}
console.log(resultArray);
You result array contains [2, 4, 52].
I hope this helps.
JS reduce method is applied against two values of array and reduce these two values of array ( a and b) into one (c) based on defined condition (return c = a+b ).
Here in your case the condition was which among two is greater (a>b?a:b).
Currently I have an array using an increasing index:
var idx = 1;
var a = [];
a[idx++] = "apple";
a[idx++] = "orange";
...
console.log(a[2]);
And only accessing it by [], not using array specific functions, like length, indexOf, ...
Apparently following is also working in this case:
var a = {};
So, which one should I prefer in such case? For example any performance difference between them?
[ ] denotes an array. Arrays only hold values:
var a1 = [1, 2, 3, 4]
As #Qantas pointed out, array can hold more than just values. An array can even contain another array and/or object:
var a2 = [1, 2, ["apple", "orange"], {one: "grape", two: "banana"}];
{ } denotes an object. Objects have key-value pairs like
var a3 = {one: 1, two: 2}
In your case, it's really a matter of how you would like to be able to access the data. If you are only interested in knowing "apple", "pear", etc. Go ahead and use an array. You can access it via it's index
a1[0]; // outputs 1
a1[1]; // outputs 2
or you can iterate over it with a loop. If you use the curly braces, (given the example I gave) you could access it with
a3.one; // outputs 1
a3["two"]; // outputs 2
It's really up to you on how it would best fit your needs in this case. For a more extensive discussion see this article.
The difference is using square brackets will create an Array object while using curly brackets creates a plain object. For example:
a = [];
a[1] = 'a';
b = {};
b[1] = 'b';
a.length; // returns 2
b.length; // is undefined
a.push('z'); // add 'z' to the end of a
b.push('z'); // generates an error - undefined is not a function
// because plain objects don't have a push method
Read the MDN documentation on Array objects to know more about arrays: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
Alright, I'm taking an array, and making another array from it with the only difference being the indexes are displaced by an arbitrary number determined using two reference points (one in each array). Doing this creates negative indexes, which if it didn't stop the script from working, would be useful. Is there any way to have the second array have the negative indexes and work, or am I going to have to use an all-together different method? I rewrote the code to be a simple case.
var firstArray = {
field: [ 1, 2, 3, 4, 5],
referenceIndex : 2
};
var secondArray = {
referenceIndex: 1,
offset: 0,
field : {}
};
// Create secondArray.field by finding the offset.
secondArray.offset = firstArray.referenceIndex - secondArray.referenceIndex;
for (i=0; i < firstArray.field.length; i++){
alert([i - secondArray.offset, firstArray.field[i]].join(" "));
secondArray.field[i - secondArray.offset] = firstArray.field[i]; //creates a negative index.
}
An array can have (in a strict sense) only positive integer as indices. However it is also an object, so it can take any string as a property. So in a sense, it will 'work', but do not trust Array#length to have the right value.
var arr = [1,2,3];
arr.length //3
arr[10] = 10;
arr.length //11
arr["blah"] = 100;
arr.length //still 11
arr[-1] = 200;
arr.length //still 11
I'd also like to point you to this excellent article - http://javascriptweblog.wordpress.com/2010/07/12/understanding-javascript-arrays/
No you can't have negative indices and have it work properly, however, you possibly could save a number and add it to your index to create a positive value. For example you have indeces -2 through 4. In the array this would be 0 - 6 so you would need to add or subtract 2 to get to the value of the index you want.