Can't instantiate an array of objects - javascript

I'm trying to load up an array of objects that is an array itself, so to speak. So I have an array of names(members) then I'm making a master list that will have name, bugs, enhance, etc. in one row for every name. So I run a simple for loop to load master list but it is telling me that for (0) i, masterList[i].name cannot be loaded because it is undefined. Is there a way around this? Thanks
var mem = getMembers();//get a array of members
var memlen = mem.length;
var masterList = [memlen]; //set to number of members
for(i=0; i < memlen; i++){
masterList[i].name = mem[i]; //set .name to the members list name at i
masterList[i].bugs = 0;
masterList[i].enhance = 0;
masterList[i].epic = 0;
masterList[i].dev = 0;
masterList[i].high = 0;
}

To create your array with a predefined size, use this :
masterList = new Array(memlen);
(with masterList = [memlen] you were just creating an array whose first item is memlen. This wasn't so problematic because the array was automatically growing in the loop but that wasn't your intent)
After that, you need to create each masterList[i] :
var masterList = new Array(memlen);
for (var i=0; i < memlen; i++){
masterList[i] = {};
masterList[i].name = mem[i]; //set .name to the members list name at i
If you don't do it, it's undefined, hence the error you have.
I also added var in the loop declaration to avoid the accidental erasing of another variable named i.

A correct version would be:
var mem = getMembers();//get a array of members
var memlen = mem.length;
var masterList = []; //set to number of members
for(var i=0; i < memlen; i++){
masterList[i] = {
name: mem[i], //set .name to the members list name at i
bugs: 0,
enhance: 0,
epic: 0,
dev: 0,
high: 0
};
}

var x = [7]; does not create a 7-element array. it creates a single element array, index 0, with value 7. You need to do var x = array(7) instead, plus initialize each of those elements to be an object instead, within your loop.

This doesn't set a length. It just creates a new Array with a single member set to the length.
var masterList = [memlen]; //set to number of members
Since you seem to already have an Array, you can use .map to build a new one.
var mem = getMembers();
var masterList = mem.map(function(item) {
return {
name: item.name, bugs: 0, enhance: 0, epic: 0, dev: 0, high: 0
};
});

Related

For Loop only adds same object every time instead of different object properties

I am writing a for loop that is iterating over an array which contains different lines in a text document.
Each iteration I am trying to pull certain parts of each of the text data lines and add them to an object, namely localinoData.
At the end of each iteration I am trying to add the localinoData object (with each object property set to a new one) to a new array.
When just adding the string found in each line the to data array (localinoDataObjArray) I get different values for each of the array. However when I now change the localinoData object properties on each iterations and try to append that changed object to the array, i get the same object in all of the array positions, e.g when I
alert(localinoDataObjArray[x].X_COORD);
for all values of x, the X_COORD is the same.
function GetlocalinoDataFromFile(localinoDataFile){
var localinoDataObjArray = new Array();
var localinoData = {
time: null,
tagID: null,
X_COORD: null,
Y_COORD: null,
Z_COORD: null,
};
var allData = localinoDataFile.responseText;
var arrayOfDataLines = allData.split('\n');
// for each iteration, get the tagID, and the co-ords(seperate) and then
// create a localinoData object and add to array
for (var i = 0; i < arrayOfDataLines.length; i++) {
if (/tag: [0-9]{22}/.test(arrayOfDataLines[i])) {
var tagID = /tag: [0-9]{22}/.exec(arrayOfDataLines[i]);
localinoData.tagID = tagID;
}
if (/[0-9]+.[0-9]{3}, [0-9]+.[0-9]{3}, [0-9].[0-9]{3}/.test(arrayOfDataLines[i])) {
XYZ_COORDS = /[0-9]+.[0-9]{3}, [0-9]+.[0-9]{3}, [0-9].[0-9]{3}/.exec(arrayOfDataLines[i]);
temp = XYZ_COORDS.toString();
temp2 = temp.split(', ');
// Here I am changing the object to new values each loop
localinoData.X_COORD = temp2[0];
localinoData.Y_COORD = temp2[1];
localinoData.Z_COORD = temp2[2];
}
// Here I am appending the newly changed object to my array
// however the same object is being added every time
// (which corresponds to the last line in the text document)
localinoDataObjArray.push(localinoData);
}
// the object values for localinoDataObjArray[0]
// and localinoDataObjArray[50] are the exact same
alert(localinoDataObjArray[20].X_COORD);
}
I expect all of the array values to be different corresponding to the different lines in the text document. However all of the array values are the same (which equal the expected result of iteration over the last line in the text document).
I am very confused as when i = 0, it should be adding an object that has the values of the first line in my text document, however it shows the values i would expect from the last line in the document.
This is very strange to me and seems like a looping problem? I am very confused and would appreciate any help in this matter.
They are all references to the same object which you keep overwriting.
Try and make a fresh instance of localinoData in every iteration of your for loop.
function GetlocalinoDataFromFile(localinoDataFile){
var localinoDataObjArray = new Array();
var allData = localinoDataFile.responseText;
var arrayOfDataLines = allData.split('\n');
// alert(arrayOfDataLines[4]);
// for each iteration, get the tagID, and the co-ords(seperate) and then create a localinoData object and add to array
for (var i = 0; i < arrayOfDataLines.length; i++) {
var localinoData = {
time: null,
tagID: null,
X_COORD: null,
Y_COORD: null,
Z_COORD: null,
};
if (/tag: [0-9]{22}/.test(arrayOfDataLines[i])) {
var tagID = /tag: [0-9]{22}/.exec(arrayOfDataLines[i]);
localinoData.tagID = tagID;
}
if (/[0-9]+.[0-9]{3}, [0-9]+.[0-9]{3}, [0-9].[0-9]{3}/.test(arrayOfDataLines[i])) {
XYZ_COORDS = /[0-9]+.[0-9]{3}, [0-9]+.[0-9]{3}, [0-9].[0-9]{3}/.exec(arrayOfDataLines[i]);
temp = XYZ_COORDS.toString();
temp2 = temp.split(', ');
localinoData.X_COORD = temp2[0];
localinoData.Y_COORD = temp2[1];
localinoData.Z_COORD = temp2[2];
}
localinoDataObjArray.push(localinoData);
}
alert(localinoDataObjArray[20].X_COORD);
}

For loop looping one too many times

I have some code:
var cart = [];
var items = [];
var cart_node = document.querySelectorAll('#tblItineraryModuleStayDetail > tbody > tr');
var cart_as_array = Array.prototype.slice.call(cart_node, 2); // start at item 3 (2)
for(var i=0;i<cart_as_array.length;i+=2) {
items.push(cart_as_array[i]);
}
Now, in the console if I type items I get:
So I expect the loop to go around once in this instance.
Here's my loop:
for(i=0; i < items.length; i++) {
// set vars
cart[i] = {};
var name = items[i].querySelector('.txtStayRoomDescription').textContent;
var price = items[i].querySelector('.tblItinPriceSummary tr td:last-child').textContent;
var brand = items[i].querySelector('.txtStayRoomLocation').textContent;
// add to object
cart[i].name = name;
cart[i].price = price;
cart[i].brand = brand;
// add to cart array
cart.push(cart[i]);
}
Which gives:
I expected a result with array cart containing one item object not two. But it has two identical objects.
What's going on here?
You're first setting the ith element of the cart array as your object, then also pushing it onto the end; this will put two copies in, as you see.
Edit for question in comments:
Let's go through your code line by line:
for(i=0; i < items.length; i++) {
// set vars
cart[i] = {};
After cart[i] = {} puts an empty object in the cart array at index i; if there was something there before, it will be overwritten, otherwise the array will simply be added.
// stuff setting properties removed
// add to object
cart[i].name = name;
cart[i].price = price;
cart[i].brand = brand;
Now, the object at cart[i] has received the attributes you constructed. The cart array now contains an object with these name, price, and brand attributes at position i.
// add to cart array
cart.push(cart[i]);
Now, in addition to the reference at i, you've pushed a second reference to the object stored at i on to the end of the array. This will produce the behavior you are observing: the object will be in the array twice.
I would recommend changing cart[i] = {} (and the associated code that adds properties of this object) to construct the object while it is stored in a local variable, then push it on to the array at the end of the loop.
At line 3 of your code you create an empty object in your array:
cart[i] = {};
then at line 14 you push that object into your array again:
cart.push(cart[i]);
You should instead just create an object, and push it at the end:
var item = {};
// ... add properties to item ...
cart.push(item)

cannot iterate through array and change value in JS

I have to iterate through an array, change one of its values, and create another array refelecting the changes.
this is what I have so far:
JS:
var arr = new Array();
arr['t1'] = "sdfsdf";
arr['t2'] = "sdfsdf";
arr['t3'] = "sdfsdf";
arr['t4'] = "sdfsdf";
arr['t5'] = "sdfsdf";
var last = new Array();
for (var i = 0; i <= 5; i++) {
arr['t2'] = i;
last.push(arr);
}
console.log(last);
Unfortunately, these are my results
As you can see, I am not getting the results needed as 0,1,2.. instead I am getting 2, 2, 2..
This is what i would like my results to be:
How can I fix this?
You have to make a copy, otherwise you are dealing with reference to the same object all the time. As it was said before - javascript does not have associate arrays, only objects with properties.
var arr = {}; // empty object
arr['t1'] = "sdfsdf";
arr['t2'] = "sdfsdf";
arr['t3'] = "sdfsdf";
arr['t4'] = "sdfsdf";
arr['t5'] = "sdfsdf";
var last = new Array();
for (var i = 0; i <= 5; i++) {
var copy = JSON.parse(JSON.stringify(arr)); //create a copy, one of the ways
copy['t2'] = i; // set value of its element
last.push(copy); // push copy into last
}
console.log(last);
ps: you can use dot notation arr.t1 instead of arr['t1']
The array access with ['t2'] is not the problem. This is a regular JavaScript feature.
The problem is: You are adding the SAME array to "last" (5 times in code, 3 times in the screenshot).
Every time you set ['t2'] = i, you will change the values in "last" also, because they are actually just references to the same array-instance.
You must create a copy/clone of the array before you add it to "last".
This is what will happen in all languages where arrays are references to objects (Java, C#...). It would work with C++ STL though.

Javascript Creating Arrays with Unique Names with a for loop

I've got a real doosy on my hands, a real doosy indeed.
I'm trying to make an array with values that are arrays with unique names.
The problem is that I just overwrite the same Eventarrayarray!
var Eventarray = new Array(); var Eventarrayarray = new Array();
for (var f = 0; f < data.events.event.length; f++) {
if(data.events.event[f].hasOwnProperty('title')) {
Eventarrayarray["marker"] = marker[f];
Eventarrayarray["content"] = content[f];
Eventarrayarray["title"] = data.events.event[f].title;
Eventarrayarray["description"] = data.events.event[f].description;
Eventarrayarray["start_time"] = data.events.event[f].start_time;
Eventarrayarray["venue"] = data.events.event[f].venue_name;
Eventarrayarray["city"] = data.events.event[f].city;
Eventarrayarray["state"] = data.events.event[f].state;
Eventarray[f] = Eventarrayarray;
}
}
console.log(Eventarray);
WHAT GIVES?!!
I haven't heard of a doosy yet, but I think you'll need to instantiate a separate Eventarrayarray Array instance for each iteration:
for (var f = 0; f < data.events.event.length; f++) {
if (data.events.event[f].hasOwnProperty('title')) {
var Eventarrayarray = new Array();
Eventarrayarray["marker"] = marker[f];
...
Eventarray[f] = Eventarrayarray;
}
Edit: Although this change should address your initial concern, it remains a non-standard way of assigning element values to an array (read: An Array doesn't work like that). It would appear that you intended to use an object instead:
for (var f = 0; f < data.events.event.length; f++) {
if (data.events.event[f].hasOwnProperty('title')) {
Eventarray[f] = {
marker: marker[f],
...
};
}
Just a comment:
The Eventeventarray should be an object (arrays are just objects with a special length property, you are using an array like an object and not using any of its array specialness), here's what I think you're trying to create:
eventArray = [
{
marker: marker[f],
content: content[f],
title: data.events.event[f].title,
description: data.events.event[f].description,
start_time: data.events.event[f].start_time,
venue: data.events.event[f].venue_name,
city: data.events.event[f].city,
state: data.events.event[f].state
}
];
Also, variable names starting with a capital letter are, by convention, reserved for constructors. Try to keep names descriptive of the content, not the structure, so events might be an array of individual event objects:
var events = [event, event, ...];

Two dimensional array in Javascript, [num][value1, value2, value3]

I'm trying to create a 2D array in JS that I can return from my method. I basically want to do something like this:
var msg[][4] = [][entryID, entryName, entryURL, entryDesc];
for (var i = 0, len = bookmarks.length; i < len; i++) {
var id = bookmarks[i].getElementsByTagName('id')[0].firstChild.nodeValue;
var name = bookmarks[i].getElementsByTagName('name')[0].firstChild.nodeValue;
var url = bookmarks[i].getElementsByTagName('url')[0].firstChild.nodeValue;
var desc = bookmarks[i].getElementsByTagName('desc')[0].firstChild.nodeValue;
msg[i][entryID] = id;
msg[i][entryName] = name;
msg[i][entryURL] = entryURL;
msg[i][entryDesc] = entryDesc;
}
The first line msg[][4] throws an error. I'm not sure if or how I can do something like that. Thanks.
If entryID etc is supposed to be a string, then I think what you actually want is an array of objects:
var msg = [];
for (var i = 0, len = bookmarks.length; i < len; i++) {
msg.push({
entryID: bookmarks[i].getElementsByTagName('id')[0].firstChild.nodeValue,
entryName: bookmarks[i].getElementsByTagName('name')[0].firstChild.nodeValue,
entryURL: bookmarks[i].getElementsByTagName('url')[0].firstChild.nodeValue,
entryDesc: bookmarks[i].getElementsByTagName('desc')[0].firstChild.nodeValue,
});
}
You can then access e.g. the second entry with msg[1].entryID. Instead of creating an object, you can simply create an array as well, but using an object is more descriptive in my opinion.
JavaScript does not have multi-dimensional arrays. What you can create are arrays of arrays (of arrays...) or arrays of objects (of arrays/objects ...). Arrays in JavaScript are dynamic, therefore it is not necessary to initialize them with any size. Just keep adding whatever vaue you want to the array.

Categories