javascript push multidimensional array - javascript

I've got something like that:
var valueToPush = new Array();
valueToPush["productID"] = productID;
valueToPush["itemColorTitle"] = itemColorTitle;
valueToPush["itemColorPath"] = itemColorPath;
cookie_value_add.push(valueToPush);
the result is [];
what am i do wrong?

Arrays must have zero based integer indexes in JavaScript. So:
var valueToPush = new Array();
valueToPush[0] = productID;
valueToPush[1] = itemColorTitle;
valueToPush[2] = itemColorPath;
cookie_value_add.push(valueToPush);
Or maybe you want to use objects (which are associative arrays):
var valueToPush = { }; // or "var valueToPush = new Object();" which is the same
valueToPush["productID"] = productID;
valueToPush["itemColorTitle"] = itemColorTitle;
valueToPush["itemColorPath"] = itemColorPath;
cookie_value_add.push(valueToPush);
which is equivalent to:
var valueToPush = { };
valueToPush.productID = productID;
valueToPush.itemColorTitle = itemColorTitle;
valueToPush.itemColorPath = itemColorPath;
cookie_value_add.push(valueToPush);
It's a really fundamental and crucial difference between JavaScript arrays and JavaScript objects (which are associative arrays) that every JavaScript developer must understand.

Use []:
cookie_value_add.push([productID,itemColorTitle, itemColorPath]);
or
arrayToPush.push([value1, value2, ..., valueN]);

In JavaScript, the type of key/value store you are attempting to use is an object literal, rather than an array. You are mistakenly creating a composite array object, which happens to have other properties based on the key names you provided, but the array portion contains no elements.
Instead, declare valueToPush as an object and push that onto cookie_value_add:
// Create valueToPush as an object {} rather than an array []
var valueToPush = {};
// Add the properties to your object
// Note, you could also use the valueToPush["productID"] syntax you had
// above, but this is a more object-like syntax
valueToPush.productID = productID;
valueToPush.itemColorTitle = itemColorTitle;
valueToPush.itemColorPath = itemColorPath;
cookie_value_add.push(valueToPush);
// View the structure of cookie_value_add
console.dir(cookie_value_add);

Related

JSON stringify does not convert array [duplicate]

In the example below, the array2.length is only 10, while in my mind, it should be 13.
Why does the "string keyed" indexes not increase the length of the array?
I can store things and still access it, and the VS debugger shows that those arrays are being stored properly. So why is the length not increased?
var array2 = new Array();
array2["a"] = new Array();
array2["b"] = new Array();
array2["c"] = new Array();
for (var i = 0; i < 10; ++i)
array2[i] = new Array();
var nothing = "";
for (var i = 0; i < array2.length; ++i)
nothing = "";
Javascript arrays cannot have "string indexes". A Javascript Array is exclusively numerically indexed. When you set a "string index", you're setting a property of the object. These are equivalent:
array.a = 'foo';
array['a'] = 'foo';
Those properties are not part of the "data storage" of the array.
If you want "associative arrays", you need to use an object:
var obj = {};
obj['a'] = 'foo';
Maybe the simplest visualization is using the literal notation instead of new Array:
// numerically indexed Array
var array = ['foo', 'bar', 'baz'];
// associative Object
var dict = { foo : 42, bar : 'baz' };
Because the length is defined to be one plus the largest numeric index in the array.
var xs = [];
xs[10] = 17;
console.log( xs.length ); //11
For this reason, you should only use arrays for storing things indexed by numbers, using plain objects instead if you want to use strings as keys. Also, as a sidenote, it is a better practice to use literals like [] or {} instead of new Array and new Object.
You're not adding items to the array; you're adding properties to the Array object.
As said above, use object for associative arrays.
If you don't you won't necessarily notice you're doing it wrong, until you innocently use "length" as an array index :
var myArray = [];
myArray["foo"] = "bar"; //works
console.log(myArray["foo"]) //print "bar"
myArray["length"] = "baz" //crash with a "RangeError: Invalid array length"
That is because you are replacing the length attribute of an array with a String, which is invalid.
"string keyed" indexes are not indexes at all, but properties. array2["a"] is the same as saying array2.a. Remember that you can set properties on any kind of variable in javascript, which is exactly what you're doing here.
You can push object to array, it will automatically get indexed (integer). If you want to add index as you want then you want to make it as object
If you want to use an object's properties as if they were like instances of a string indexed array, the work around for the length is:
var myArray = new Array();
myArray["a"] = 'foo';
myArray["b"] = 'bar';
myArray["c"] = 'baz';
let theLength = Object.keys(myArray).length

Convert String to already declared object in JavaScript?

I have this code:
//Arguments are unique.
var Object1 = new Object(argument,argument,argument);
var Object2 = new Object(argument,argument,argument);
var Object3 = new Object(argument,argument,argument);
//...
var Object100 new Object(argument,argument,argument);
function convert(){
var array = ["Object1","Object56"];
// Manipulate values in array above as if they were the objects already
//declared above this function, like acessing "Object56.argument" property.
}
I need to convert the the strings in the array to the objects that have already been declared, in order to manipulate the objects properties (which are converted from the arguments) in a function. I realize I'm basically turning JS objects into a database which is probably a bad idea but I was wondering if there's a solution to this? They way the values in the array are chosen is fairly complex and I think it would detract from the question, but they are randomly generated more or less.
Instead of storing each object as a separate variable, create a map:
var objectMap = {
Object1: new Object(argument, argument, argument),
Object2: new Object(argument, argument, argument),
// ...
Object100: new Object(argument, argument, argument)
};
The mapping would then be easy enough.
You can either do it manually:
var array = ['Object1', 'Object2'];
var objects = [];
for(var i = 0; i < array.length; i++) {
var key = array[i];
objects.push(objectMap[key]);
}
Or (if you're supporting ES5) use the map function:
var array = ['Object1', 'Object2'];
var objects = array.map(function (key) {
return objectMap[key];
});

Strange behavior in jQuery loop with arrays

I am having an issue with the following code:
var samount = [{value:100, name:'USD'},
{value:200, name:'USD'},
{value:100, name:'USD'}];
var object1 = new Array;
objects1 = samount;
var categories1 = new Array();
var groupedObjects1 = [];
var output1 = '';
var i = 0;
console.log(samount);
_.each(objects1,function(obj){
var existingObj;
if($.inArray(obj.currency,categories1) >= 0) {
existingObj = _.find(objects1,function(o){return o.currency === obj.currency;});
existingObj.value += obj.value;
} else {
groupedObjects1[i] = obj;
categories1[i] = obj.currency;
i++;
}
});
console.log(samount);
console.log(groupedObjects1);
The problem is that I do not want that samount variable to change after looping, so I have done this:
var object1 = new Array;
objects1 = samount;
The goal of this script is to sum up all values from the same currencies, but still to not mess with the initial array.
But it still changes the initial Array. Could anyone help me with this error?
Copy the array with slice
var objects1 = samount.slice(0);
Arrays and object are passed by "reference" (not really, but doesn't matter here), so when assigning an array to a new variable, all you get is a reference to the same array, not a new array.
You need to deep copy the initial array instead of affecting it.
var samount = [{value:100, name:'USD'},
{value:200, name:'USD'},
{value:100, name:'USD'}];
var object1 = $.extend(true, [], samount);
You were doing an affectation (i.e. 2 variables pointing to the same object) where you needed a copy (2 variables pointing to 2 different objects)
The problem is you're not creating a copy with
objects1 = samount
In most OO languages, you can only copy primitive types so int, strings characters etc, but not objects.
This is somewhat similar in javascript in the sense that {} is an object, same as Array or [].
So if you want to copy an object you'd have to iterate over every element of that object till you find an primitive type. This can be tedious and quite hard even (http://andrewdupont.net/2009/08/28/deep-extending-objects-in-javascript/) this is called a deep copy.
But in this case a shallow copy (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) is enough
var objects1 = samount.slice(0);

Why does a string index in an array not increase the 'length'?

In the example below, the array2.length is only 10, while in my mind, it should be 13.
Why does the "string keyed" indexes not increase the length of the array?
I can store things and still access it, and the VS debugger shows that those arrays are being stored properly. So why is the length not increased?
var array2 = new Array();
array2["a"] = new Array();
array2["b"] = new Array();
array2["c"] = new Array();
for (var i = 0; i < 10; ++i)
array2[i] = new Array();
var nothing = "";
for (var i = 0; i < array2.length; ++i)
nothing = "";
Javascript arrays cannot have "string indexes". A Javascript Array is exclusively numerically indexed. When you set a "string index", you're setting a property of the object. These are equivalent:
array.a = 'foo';
array['a'] = 'foo';
Those properties are not part of the "data storage" of the array.
If you want "associative arrays", you need to use an object:
var obj = {};
obj['a'] = 'foo';
Maybe the simplest visualization is using the literal notation instead of new Array:
// numerically indexed Array
var array = ['foo', 'bar', 'baz'];
// associative Object
var dict = { foo : 42, bar : 'baz' };
Because the length is defined to be one plus the largest numeric index in the array.
var xs = [];
xs[10] = 17;
console.log( xs.length ); //11
For this reason, you should only use arrays for storing things indexed by numbers, using plain objects instead if you want to use strings as keys. Also, as a sidenote, it is a better practice to use literals like [] or {} instead of new Array and new Object.
You're not adding items to the array; you're adding properties to the Array object.
As said above, use object for associative arrays.
If you don't you won't necessarily notice you're doing it wrong, until you innocently use "length" as an array index :
var myArray = [];
myArray["foo"] = "bar"; //works
console.log(myArray["foo"]) //print "bar"
myArray["length"] = "baz" //crash with a "RangeError: Invalid array length"
That is because you are replacing the length attribute of an array with a String, which is invalid.
"string keyed" indexes are not indexes at all, but properties. array2["a"] is the same as saying array2.a. Remember that you can set properties on any kind of variable in javascript, which is exactly what you're doing here.
You can push object to array, it will automatically get indexed (integer). If you want to add index as you want then you want to make it as object
If you want to use an object's properties as if they were like instances of a string indexed array, the work around for the length is:
var myArray = new Array();
myArray["a"] = 'foo';
myArray["b"] = 'bar';
myArray["c"] = 'baz';
let theLength = Object.keys(myArray).length

Function 'concat' (in JavaScript) is not working for associative arrays

I have a problem concatenating two associative arrays in JavaScript. Below is the sample code:
var firstArray = new Array();
firstArray.c1 = "sam";
firstArray.c2 = "kam";
var secArray = new Array();
secArray.c3 = "sam";
secArray.c4 = "kam";
var res = firstArray.concat(secArray);
Is this a known limitation?
What's the best way to achieve this?
You are not using Array functionality - just Object functionality. In JavaScript, Object is an associative array - you use Array for arrays indexed by integers. If you did
var firstArray = new Array();
firstArray.push("sam");
firstArray.push("kam");
var secArray = new Array();
secArray.push("sam");
secArray.push("kam");
var res = firstArray.concat(secArray);
then concat would work as expected.
If you actually want to merge associative arrays, do:
for (var attr in src_array) { dest_array[attr] = src_array[attr]; }
This will of course overwrite existing keys in dest_array which have counterparts in src_array.
Try this:
var firstArray = new Array("sam", "kam");
var secArray = new Array("sam", "kam");
var res = firstArray.concat(secArray);
Arrays in JavaScript have only numerical keys. Only objects can have non numerical properties. So try this instead:
var firstArray = {};
firstArray.c1 = "sam";
firstArray.c2 = "kam";
var secArray = {};
secArray.c3 = "sam";
secArray.c4 = "kam";
for (var prop in secArray) {
if (secArray.hasOwnProperty(prop)) {
firstArray[prop] = secArray[prop];
}
}
JavaScript doesn't have associative arrays; it has object hashes. You're creating an array and assigning values to some of its properties, not in the array itself.
Your concat will not work because the values are object properties. To do a concat the way you have it, you'll need to combine the two objects. YUI, jQuery, and the other JavaScript frameworks provide helpful methods to do just that.
Strictly speaking, those aren't associative arrays at all: they are arrays of zero length, with additional named properties. Assigning those properties works because arrays are also objects in JavaScript; but that doesn't make them an associative array. It's better to look at them as hashes.
Array methods such as concat will only work with the numerically-indexed elements of arrays, not with the properties of objects - even if those objects happen to be arrays.

Categories