Javascript Creating Arrays with Unique Names with a for loop - javascript

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, ...];

Related

How can I add values from existing object to new object dynamically?

Currently, I have an empty new object and I want to populate values from an existing object to new object because I want to use an object with only limited properties from the existing object (e.g. I only want the four properties instead of eight).
Here's how I am doing the mapping so far:
const newObject: any = {};
for (let i = 0; i < this.PRODUCT_DATA.length; i++) {
newObject._productSkuKey = this.PRODUCT_DATA[i]._productSkuKey;
newObject._storeKey = this.itemPriceForm.get('location').value;
newObject._price = this.PRODUCT_DATA[i]._price;
newObject._status = this.PRODUCT_DATA[i]._isActive;
this.updatedProducts.push(newObject);
}
So far, it looks to be storing the values from the existing object to newObject. However, it is only saving the last object values and not the different values from the object. How can I fix this to save all values (not just the last values for every object in the array)?
You need to make a copy of that before pushing in array
const newObject: any = {};
for (let i = 0; i < this.PRODUCT_DATA.length; i++) {
newObject._productSkuKey = this.PRODUCT_DATA[i]._productSkuKey;
newObject._storeKey = this.itemPriceForm.get('location').value;
newObject._price = this.PRODUCT_DATA[i]._price;
newObject._status = this.PRODUCT_DATA[i]._isActive;
this.updatedProducts.push(Object.assign({}, newObject));
// Or
// this.updatedProducts.push({ ...newObjec });
}
Or Simply create object inside loop. I love to use Array.prototype.forEach and Array.prototype.map
this.updatedProducts = this.PRODUCT_DATA.map(({_productSkuKey, _price, _isActive})=> ({
_productSkuKey,
_storeKey: this.itemPriceForm.get('location').value,
_price,
_status: _isActive
});
Avoid declaring newObject as 'const'. This is an updated code that works for me.
//avoid using a const, as you cannot override it
let newObject: any = {};
for (let i = 0; i < this.PRODUCT_DATA.length; i++) {
newObject._productSkuKey = this.PRODUCT_DATA[i]._productSkuKey;
newObject._storeKey = this.itemPriceForm.get('location').value;
newObject._price = this.PRODUCT_DATA[i]._price;
newObject._status = this.PRODUCT_DATA[i]._isActive;
this.updatedProducts.push(newObject);
//after pushing the object, empty all the current contents
newObject={};
}

Issue with returning values from an object array

I'm pretty new (a few weeks in) to js and have a question about an incremental game I'm developing. My issue has to do with creating an array from an object I have and then fetching a property of the object, which is used in a compare statement and updated in my HTML.
I have the following object called UPGRADES:
var UPGRADES = {
newClothes: {
name: "New Clothes",
desc: "Give your bums a new look and some more motivation! \n Bum
production bonus: 100%",
moneyCost: 1000,
scienceCost: 10,
requiredScience: 10,
buildingAffected: BUILDINGS.bumBuilding,
upgVal: 2,
id: 'newClothes'
},
//{upgrade 2}
//{upgrade 3 etc.}
}
For one part of my code I need to go through each element of UPGRADES, return the nth object WITHIN "upgrades" (with newClothes as index 0), and then call (Nth index.scienceCost).
So far I've done the following:
var numBuildings = objectLength(BUILDINGS);
var numUpgrades = objectLength(UPGRADES);
function checkVisiblityOnUpgrades () {
var upgArray = [];
for (var a = 0; a < numUpgrades; a++) {
upgArray[a] = Object.keys(UPGRADES)[a].toString();
console.log(UPGRADES.upgArray[a]);
if (UPGRADES.upgArray[a].requiredScience <= resources.science) {
var idString = upgArray[a].id.toString();
getId(idString.concat("Button")).style.visibility = "visible";
getId(idString.concat("MoneyCostDisp")).innerHTML =
numFormat(upgArray[a].moneyCost);
getId(idString.concat("ScienceCostDisp")).innerHTML =
numFormat(upgArray[a].scienceCost);
}
}
}
I get this error along with it:
Uncaught TypeError: Cannot read property '0' of undefined
at checkVisiblityOnUpgrades (game.js:268)
at update (game.js:290)
268 is console.log(UPGRADES.upgArray[a]);
I was wondering how I would actually go about grabbing the values of the object I wanted. I'm creating an array in checkVisibilityOnUpgrades() so I can iterate through each upgrade with a for loop.
Another question I have is: If I was going to store 100+ instances of upgrades, would it be better to switch UPGRADES to an array rather than its own object? That way I could grab values a lot more easily.
You can drastically simplify your initial logic there with Object.entries:
Object.entries(UPGRADES).forEach(({ key, thisUpgradeObject }) => {
// `key` references the outer property, eg., 'newClothes'
// `thisUpgradeObject` references the inner object
});
So
Object.entries(upgArray).forEach(({ key, obj }) => {
const {
requiredScience,
id,
moneyCost,
scienceCost,
} = obj;
if (requiredScience < resources.science) return;
const idString = id.toString();
getId(idString.concat("Button")).style.visibility = "visible";
getId(idString.concat("MoneyCostDisp")).innerHTML = numFormat(moneyCost);
getId(idString.concat("ScienceCostDisp")).innerHTML = numFormat(scienceCost);
});
I see the problem here:
You create an array called upgArray, but then try to access UPGRADES.upgArray which is undefined. What you want to write there is likely UPGRADES[upgArray[a]].
function checkVisiblityOnUpgrades () {
var upgArray = Object.keys(UPGRADES);
for (var a = 0; a < numUpgrades; a++) {
if (UPGRADES[upgArray[a]].requiredScience <= resources.science) {
var idString = UPGRADES[upgArray[a]].id.toString();
getId(idString.concat("Button")).style.visibility = "visible";
getId(idString.concat("MoneyCostDisp")).innerHTML =
numFormat(UPGRADES[upgArray[a]].moneyCost);
getId(idString.concat("ScienceCostDisp")).innerHTML =
numFormat(UPGRADES[upgArray[a]].scienceCost);
}
}
}

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.

Can't instantiate an array of objects

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
};
});

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