fastest way of getting an array of references from object keys - javascript

Suppose I have a global object that looks like this:
var TheFruits = {
323: {},
463: {},
223: {} ..... // can be thousands of properties
}
Basically, the keys are IDs and the values are themselves objects. Now suppose I have an array of IDs that I pass into a function and I want that function to return an array of references to the values that match the IDs of the global object (ie. no deep copy). Something like this:
function GetReferences(TheArrayOfIDs) {
var TheArrayOfReferences = [];
return TheArrayOfReferences;
}
Now I know I can write a for loop that iterates over TheArrayOfIDs and that then loops over the object keys at each iteration but then that's a loop within a loop. So I'm looking for the fastest way of doing it, and jquery is available.
Basically, if TheArrayOfIDs = [323, 463, 223]; then TheArrayOfReferences =[TheFruit.323, TheFruit.463, TheFruit.223];
Thanks.

You don't need a second loop:
var results = [];
for (var i = 0; i < ids.length; i++)
results.push(fruits[ids[i]]);

You have to do only one loop as key look-up is built-in :
var TheArrayOfReferences = TheArrayOfIDs.map(function(id){return TheFruits[id]});

Something like that should work :
var i = 0, l = TheArrayOfIDs.length;
for (i = 0; i < l; i++)
TheArrayOfReferences.push(TheFruits[TheArrayOfIDs[i]]);

Related

Copying array onto the "this" variable (creating an Array-like object)

Is there a better way to copy an array onto the this variable
function obj(arr) {
for (var i=0, l=arr.length; i<l; ++i) {
this[i] = arr[i];
}
this.length = arr.length;
}
var o = new obj([1,2,3,4]);
console.log(o[0]); // Outputs 1
Is there any other way to do it, instead of iterating over the whole arr ?
You can use Array#push this way:
function obj(arr) {
Array.prototype.push.apply(this, arr);
}
This will treat this like an array, adding all the elements from arr and setting length correctly. See also Function#apply.
But of course there is still an internal loop. You cannot copy / move a collection values to another collection without iterating over it (unless, I guess, the collections use structural sharing)
You could do it like this:
function obj() {
return this;
}
var o = obj.apply([1,2,3,4]);
console.log(o[0]); // Outputs 1

How To Create Dynamic Arrays Varaibles in Javascript

Can you please let me know if it is possible to create dynamically sets of arrays in JS? I tried some thing like this but didn't work
for (i = 0; i < 3; i++) {
var item[i] = [];
}
item1.push(1);
console.log(item1);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
You're almost there. Assuming you're trying to create a two dimensional array (an array of arrays), you just have to declare the top level array and then reference the first level array with [x] array syntax like this:
var items = [];
for (i = 0; i < 3; i++) {
items[i] = [];
}
// Here items is an array of arrays where each first level array entry
// is an empty array. You can then put things into those empty arrays
// You can reference the first level array here
items[1].push(1);
items[1].push(2);
console.log(items[1]); // [1,2]

Sort a three dimensional array in Javascript

Consider this Array
var LIST =[];
LIST['C']=[];
LIST['B']=[];
LIST['C']['cc']=[];
LIST['B']['bb']=[];
LIST['C']['cc'].push('cc0');
LIST['C']['cc'].push('cc1');
LIST['C']['cc'].push('cc2');
LIST['B']['bb'].push('bb0');
LIST['B']['bb'].push('bb1');
LIST['B']['bb'].push('bb2');
I can loop through this array like
for(var i in LIST){
console.log(i)//C,B
var level1=LIST[i];
for(var j in level1){
console.log(j)//cc,bb
// etc...
}
}
Fine.. I have few basic questions.
1.How to sort the array in each level?
One level can be sort by .sort(fn) method . How can i pass to inner levels?
2.Why the indexOf method does not works to find the elements in first two levels?
If it's because of the a non string parameter .. how can i search an array items in array if the item is not string?
3.How for(var i in LIST) works ?
I just need a basic understanding of indexing and looping through array ..
Thanks ..
LIST is NOT a three dimensional array in Javascript, it is just an array.
//declare an array which names LIST.
var LIST = [];
//set a property named 'C' of the LIST to be an array.
LIST['C']=[];
//set a property named 'B' of the LIST to be an array.
LIST['B']=[];
//set a property named 'cc' of the 'LIST.C'(which is an array object)
LIST['C']['cc']=[];
//set a property named 'bb' of the 'LIST.B'(which is an array object)
LIST['B']['bb']=[];
The fact is you only need to let the last level to be an array, see my example code below.
function iterateOrderd(obj) {
if (obj instanceof Array) {
obj.sort();
for (var j = 0, l=obj.length; j < l; j++) {
console.log(obj[j]);
}
} else {
var sortable = [];
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
sortable.push(i);
}
}
sortable.sort();
for (var j = 0, l=sortable.length; j < l; j++) {
console.log(sortable[j]);
iterateOrderd(obj[sortable[j]]);
}
}
}
var LIST = {};
LIST['C'] = {};
LIST['B'] = {};
LIST['C']['cc']=[];
LIST['B']['bb']=[];
LIST['C']['cc'].push('cc0');
LIST['C']['cc'].push('cc1');
LIST['C']['cc'].push('cc2');
LIST['B']['bb'].push('bb0');
LIST['B']['bb'].push('bb1');
LIST['B']['bb'].push('bb2');
iterateOrderd(LIST);
You need to know that Array inherits from Object.
In JavaScript, any Object instance is an associative array(!), so acts like an Array in PHP. For example:
var o = {}; // or new Object();
o['foo'] = 'bar';
o[0] = 'baz';
for (i in o) { console.log(i, o[i]); }
Sorting an Object does not make much sense. indexOf would kinda work in theory, but is not implemented.
Arrays are ordered lists. Array instances have push(), length, indexOf(), sort() etc., but those only work for numerical indexes. But again, Array inherits from Object, so any array can also contain non-numerical index entries:
var a = []; // or new Array();
a[0] = 'foo'; // a.length is now 1
a.push('baz'); // a[1] === 'baz'
a.qux = 1; // will not affect a.length
a.sort(); // will not affect a.qux
for (i in a) { console.log(i, a[i]); }
I recommend playing around with arrays and objects, and you'll soon get the point.
What is your sorting criteria ? I mean how will you say array firstArray comes before secondArray?
regarding the for (counter in myArray), counter will take values of an array element in every iteration.
for (counter in [0,1,5]), counter will have values 0, 1 and 5 in the 3 iterations.
In your case, i will have values LIST['B'] and LIST['C'] in the two iterations and j will have values LIST['B']['bb'], LIST['B']['cc'], LIST['C']['bb'] and LIST['C']['cc'].
Both i and j will be arrays.

sum index in JavaScript foreach

In the following code sample i get a strange behavior
var data = ['xxx', 'yyy'];
for (var i in data)
{
var a = i;
var b = data[i];
}
The two first iterations works just fine. I get index "0" and "1" in i, but then it loops one extra time and now the i is "sum". Is this by design or what is this extra iteration used for? The result in my case is always empty and it messes up my code. Is there a way to not do his extra loop?
BR
Andreas
It looks like you (or some other code you've included) have added extra properties onto the Array prototype. What you should be doing is checking to see whether the object you're iterating over actually has that property on itself, not on its prototype:
for (i in data) {
if (data.hasOwnProperty(i)) {
a = i;
b = data[i];
}
}
That said, you should never use for .. in on arrays. Use a regular for loop.
See here for more information: http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
You are looping through an Array, not through an Object. For arrays it's better to use:
for (var i=0; i<data.length; i=i+1){
/* ... */
}
In your loop every property of the Array object is taken into account. That makes the for ... in loop for array less predictable. In your case it looks like sum is a property (method) that's added to Array.prototype elsewhere in your code.
There are more ways to loop through arrays. See for example this SO-question, or this one
Just for fun, a more esoteric way to loop an array:
Array.prototype.loop = function(fn){
var t = this;
return (function loop(fn,i){
return i ? loop(fn,i-1).concat(fn(t[i-1])) : [];
}(fn,t.length));
}
//e.g.
//add 1 to every value
var a = [1,2,3,4,5].loop(function(val){return val+1;});
alert(a); //=> [2,3,4,5,6]
//show every value in console
var b = [1,2,3,4,5].loop(function(val){return console.log(val), val;});
Here's a way to safely iterate.
var data = ['xxx', 'yyy'];
for (var i = 0; i < data.length; i++)
{
var a = i;
var b = data[i];
}
What you are getting is an method coming from extending the Array object, I guess you are using some library where is something like
Array.prototype.sum = function () {...};
Perhaps setting data like this would work better: var data = {0:'xxx', 1:'yyy'};
First of all data is an object. Try to add console.log(a); and console.log(b); inside your loop and you'll see.

JavaScript Array

I usually script/program using python but have recently begun programming with JavaScript and have run into some problems while working with arrays.
In python, when I create an array and use for x in y I get this:
myarray = [5,4,3,2,1]
for x in myarray:
print x
and I get the expected output of:
5
4
3
..n
But my problem is that when using Javascript I get a different and completely unexpected (to me) result:
var world = [5,4,3,2,1]
for (var num in world) {
alert(num);
}
and I get the result:
0
1
2
..n
How can I get JavaScript to output num as the value in the array like python and why is this happening?
JavaScript and Python are different, and you do things in different ways between them.
In JavaScript, you really should (almost) always iterate over an array with a numeric index:
for (var i = 0; i < array.length; ++i)
alert(array[i]);
The "for ... in" construct in JavaScript gives you the keys of the object, not the values. It's tricky to use on an array because it operates on the array as an object, treating it no differently than any other sort of object. Thus, if the array object has additional properties — which is completely "legal" and not uncommon — your loop will pick those up in addition to the indexes of the "normal" array contents.
The variable num contains the array item's index, not the value. So you'd want:
alert(world[num])
to retrieve the value
The for var in... loop in JavaScript puts the keys in the variable instead of the actual value. So when using for var ... you should do something like this:
var world = [5, 4, 3, 2, 1];
for ( var key in world ) {
var value = world[key];
alert(key + " = " + value);
}
And note that this way of looping is best used when you're using objects instead of arrays. For arrays use the common:
for ( var i = 0, j = arr.length; i < j; i++ ) { ... }
Or if you're targeting modern browser you can use the forEach-method of arrays:
var arr = [1, 2, 3];
arr.forEach(function(num) {
alert(num);
});
The for...in loop loops over all key elements; not the values.
I would recommend you to use
for(var i=0; i<arr.length; i++){
alert(arr[i]);
}
When you use the in operator num becomes a key. So simply use this key to get a value out of the array.
var world = [5,4,3,2,1]
for (var num in world) {
alert(world[num]);
}
try this.
var world = [5,4,3,2,1]
for(var i=0;i<world.length;i++){
alert(world[i])
}
Because javascript in your case is printing the index of the element, not the value.
the result you got is just element index,if you want to get element value
your code should like this
var world = [5,4,3,2,1]
for (var num in world) {
alert(world[num]);
}
The for in iteration in JavaScript works only for the object data type. The way it works is that it lets you iterate over the attributes of an object. arrays are objects in JavaScript, but the for in only works on its attributes, not the array values.
For example you might define an array as such:
var arr = [1,2,3];
And you can assign attributes to this array, because it's actually an object:
arr.foo = "bar";
arr["1"] = 2;
Now when you use the for in iteration method you will be able to iterate over the attributes we just assigned above;
for(var i in arr) console.log(i);
To iterate over the actual array values you need to use the for(var i=0; i<arr.length; i++) construct.
Hope this helps.
In javascript it's advised to loop Arrays different from looping Objects. You are using an object loop, which may return unexpected result (for instance if the Array.prototype was extended with custom methods you would iterate those too, and it does't guarantee the order of the array is preserved). There are many ways to loop through an array, using it's index:
// regular
var arr = [1,2,3,4,5]
,i
;
for (i=0;i<arr.length;i++) {
console.log(arr[i]);
}
// using while
var arr = [1,2,3,4,5]
,i = 0
;
while ((i = i + 1)<arr.length) {
console.log(arr[i]);
}
// using while reversed
var arr = [1,2,3,4,5]
,i = arr.length
;
while ((i = i - 1) > -1) {
console.log(arr[i]);
}
Note: Why not use i++ or i--? To avoid confusion, index out of range-errors and to satisfy JSLint

Categories