iteratively adding to an array of objects in Javascript - javascript

I am trying to create an object iteratively with the following structure:
var series = {
data: [{
name: 'some text',
y: 0
},
{
name: 'some other text',
y: 1
}]
}
Below is my code so far:
var series = {
data: []
};
var datatemp = {
y: '',
name: ''
};
for (var i=0; i<10; i++) {
datatemp.y = i;
datatemp.name = "namelabel"+i;
series.data.push(datatemp);
}
But what I am getting is the final values of series.data[i].y and series.data[i].name in all elements of the array, rather than what I expect, which is different values as the counter i iterates. I would appreciate your guidance on what I am doing wrong. Thanks in advance!

To add to what Mimisbrunnr said, you could even do it this way:
for (var i=0; i<10; i++) {
series.data.push({y: i, name: "namelabel"+i});
}
There is no need for the intermediate variable.

You need to make a new datatemp for each iteration of the for loop otherwise you are just passing the same object into the array each time and modifying it's values.
for (var i=0; i<10; i++) {
var datatemp = {};
datatemp.y = i;
datatemp.name = "namelabel"+i;
series.data.push(datatemp);
}

var series = {
data: []
};
for (var i=0; i<10; i++) {
var datatemp={};
datatemp.y = i;
datatemp.name = "namelabel"+i;
series.data.push(datatemp);
}
for (var i=0; i<10; i++) {
console.log(series.data[i].y);
console.log(series.data[i].name);
}
http://jsfiddle.net/Vp8EV/

Objects are passed by reference in javascript, in your example you only have one object which is referenced by the name datatemp, every time you assign a new value to one of its members the old member gets overwritten, so you have to create a new object for each iteration of the loop.

Related

JavaScript: How do I avoid an "undefined" error when assigning object property values to an array? [duplicate]

I need to create an array of object literals like this:
var myColumnDefs = [
{key:"label", sortable:true, resizeable:true},
{key:"notes", sortable:true,resizeable:true},......
In a loop like this:
for (var i = 0; i < oFullResponse.results.length; i++) {
console.log(oFullResponse.results[i].label);
}
The value of key should be results[i].label in each element of the array.
var arr = [];
var len = oFullResponse.results.length;
for (var i = 0; i < len; i++) {
arr.push({
key: oFullResponse.results[i].label,
sortable: true,
resizeable: true
});
}
RaYell's answer is good - it answers your question.
It seems to me though that you should really be creating an object keyed by labels with sub-objects as values:
var columns = {};
for (var i = 0; i < oFullResponse.results.length; i++) {
var key = oFullResponse.results[i].label;
columns[key] = {
sortable: true,
resizeable: true
};
}
// Now you can access column info like this.
columns['notes'].resizeable;
The above approach should be much faster and idiomatic than searching the entire object array for a key for each access.
You can do something like that in ES6.
new Array(10).fill().map((e,i) => {
return {idx: i}
});
This is what Array#map are good at
var arr = oFullResponse.results.map(obj => ({
key: obj.label,
sortable: true,
resizeable: true
}))
This will work:
var myColumnDefs = new Object();
for (var i = 0; i < oFullResponse.results.length; i++) {
myColumnDefs[i] = ({key:oFullResponse.results[i].label, sortable:true, resizeable:true});
}
In the same idea of Nick Riggs but I create a constructor, and a push a new object in the array by using it. It avoid the repetition of the keys of the class:
var arr = [];
var columnDefs = function(key, sortable, resizeable){
this.key = key;
this.sortable = sortable;
this.resizeable = resizeable;
};
for (var i = 0; i < len; i++) {
arr.push((new columnDefs(oFullResponse.results[i].label,true,true)));
}
If you want to go even further than #tetra with ES6 you can use the Object spread syntax and do something like this:
const john = {
firstName: "John",
lastName: "Doe",
};
const people = new Array(10).fill().map((e, i) => {(...john, id: i});
I'd create the array and then append the object literals to it.
var myColumnDefs = [];
for ( var i=0 ; i < oFullResponse.results.length; i++) {
console.log(oFullResponse.results[i].label);
myColumnDefs[myColumnDefs.length] = {key:oFullResponse.results[i].label, sortable:true, resizeable:true};
}
var myColumnDefs = new Array();
for (var i = 0; i < oFullResponse.results.length; i++) {
myColumnDefs.push({key:oFullResponse.results[i].label, sortable:true, resizeable:true});
}

Dictionary inside array in Javascript

I have certain data sets. Example, A,B and C. There are sets of these values. For example:-
[A:asd, B:ajs, C:aknd],
[A:sdf, B:gss, C:fdss],
[A:ijq, B:cba, C:jqwd]
etc.
Now i want to make a dictionary containing these values as separate dictionaries. For example:-
{
{
A:asd,
B:ajs,
C:aknd
},
{
A:sdf,
B:gss,
C:fdss
},
{
A:ijq,
B:cba,
C:jqwd
}
}
Can someone help me out with this.
I tried doing this but it's not making a dictionary.
for( var i=0; i< n; i++) {
data += {
"A":value1,
"B":value2,
"C":value3
}
}
Any inputs?
This does not make sense in Javascript:
{
{
A:asd,
B:ajs,
C:aknd
},
{
A:sdf,
B:gss,
C:fdss
},
{
A:ijq,
B:cba,
C:jqwd
}
}
If you intend to have an object (dictionary) with integer keys, you could do it like so:
var data = {};
for( var i=0; i< n; i++) {
data[i] = {
"A":value1,
"B":value2,
"C":value3
}
}
Depending a bit on what you're trying to do, an array would likely be a better choice:
var data = [];
for( var i=0; i< n; i++) {
data.push({
"A":value1,
"B":value2,
"C":value3
});
}

Looping through an array to create an object in Javascript

I want to write a function that takes an array such as:
var columns = ['distance', 'times', 'acceleration']
Then from this array, I want to generate something like this:
[{id: id_0, distance: 0, times: 0, acceleration: 0}, {id: id_1, distance: 1, times: 1, acceleration: 1}]
Notice that we have 2 objects here, but I want it to be whatever number I pass in to my parameter. Here is what I have:
generateData: function(rows, columns) {
var generatedData = [];
for (var i = 0, rowLen = rows.length; i < rowLen; i++) {
for (var n = 0; i < columns.length; n++) {
// not sure how to construct an object here from looping through my columns array
generatedData.push({
id: 'id_ + n',
// confused here
});
}
return generatedData;
}
}
This is the perfect place to dynamically create your own function. Try this:
function createArrayOfObjects(columns, count) {
var objectProps = new Array(columns.length);
for (var i = 0; i < columns.length; i++){
//":j" will be the variable j inside the dynamic function
objectProps[i] = columns[i] + ":j";
}
var funcBody = "var arr = new Array(count);" +
"for(var j = 0; j < count; j++){" +
"arr[j] = {" + objectProps.join(',') + "};" +
"}" +
"return arr;";
//Create a new function and call it with count as the parameter, returning the results
return new Function("count", funcBody)(count);
}
var count = 10;
var columns = ['distance', 'times', 'acceleration'];
createArrayOfObjects(columns.concat('id'), count);
This has the benefit of only having to loop over the columns array once where other solutions require nested loops.
JSPerf
I am giving you away the initial non-optimized solution. Its upto you to do the optimizations.
generateData: function(rows, columns) {
var generatedData = [];
for (var i = 0; i < rows.length; i++) {
var myObj = {};
myObj["id_" + i] = i;
for (var n = 0; n < columns.length; n++) {
myObj[columns[n]] = i;
}
generatedData.push(myObj);
}
return generatedData;
}
A functional approach that will take the object properties from the passed in array, instead of hard-coding them, might look something like this inside the for loop to populate an array named 'rows' with property names coming from the values of an array named 'cols':
cols.forEach(function(cv, ci, ca) { rows[ri][cv] = ri; });
See the snippet for a full example. Note that, in this example, I'm just shoving the current index of "rows" into the object as the property value.
var columns = ['distance', 'times', 'acceleration'];
function generateData(numRows, cols) {
rows = new Array(numRows);
for(ri=0; ri < rows.length; ri++) {
rows[ri] = { id: ri };
cols.forEach(function(cv, ci, ca) {
rows[ri][cv] = ri;
});
}
return rows;
}
data = generateData(5, columns);
console.log(data);

Add different value to the same object literal javascript

I have a piece of code to create an object literal array. The array is created from 2 other string array, one will become the object literal colHeads and the other array will be the data dataArr.
colHeads = [name, state]
dataArr = [John A. Smith,Joan B. Jones]
var temp = [];
var tempObj = {};
for (var i=0; i<colHeads.length; ++i) { // columns
var dataArr = colDatas[i].split(",");
for (var j = 0; j < dataArr.length; j++) { // data
tempObj[colHeads[i]] = dataArr[j];
}
temp.push(tempObj);
}
The final array should look like this:
var data = [
{name: 'John A. Smith', state: 'CA'},
{name: 'Joan B. Jones', state: 'NY'}
];
Problem here is according to this line tempObj[colHeads[i]] = dataArr[0]; The object literal would be replaced with the last entry in both arrays which make the result look like this:
var data = [
{name: 'Joan B. Jones', state: 'NY'},
{name: 'Joan B. Jones', state: 'NY'}
];
I'm new to javascript so I don't know much the syntax
First off, your loop is accessing the same dataArr index, it should be using j
tempObj[colHeads[i]] = dataArr[j];
Second, you are not constructing new tempObjs for each loop, so each item index shares the same tempObj which will end up leaving you with a list of the same exact object.
So far your code should look something more like this:
var temp = [];
for (var i=0; i<colHeads.length; ++i) { // columns
var tempObj = {};
var dataArr = colDatas[i].split(",");
for (var j = 0; j < dataArr.length; j++) { // data
tempObj[colHeads[j]] = dataArr[j];
}
temp.push(tempObj);
}
Lastly, You are only creating one tempObj for each column, rather than each row as you should be doing.
var temp = [];
var rowCount = colDatas[0].split(',').length;
for (var i = 0; i < rowCount; ++i) { // rows first
var tempObj = {};
for (var j = 0; j < colHeads.length; ++j) { // now columns
tempObj[colheads[j]] = colDatas[j].split(',')[i];
}
temp.push(tempObj);
}
Now, due to the way your colDatas object is set up, it requires you to split them for every loop which can become pretty costly, I suggest you find another way to store that so it can be better optimized.
Create new object in cycle (prepare arrays before it), like this:
for (var i=0; i<colHeads.length; ++i) {
var tmpObj = {};
tmpObj.name = colHeads[i];
tmpObj.state = colDatas[i]
result.push(tmpObj);
}

Javascript/Node - Insertion of objects into array using for loop

I need help regarding insertion of array elements as objects into another array in Javascript. I have the following code:
tableLength = 3;
nyCourt = [];
oldArr = [Buy, String, Question]
for (var t = 0; t < tableLength; t++) {
nyCourt.push({});
for (var i = 0; i < OldArr.length; i++) {
nyCourt.Title = OldArr[i] ;
}
};
The code isnt working, I want output in the following format
[{Title:Buy },
{Title: String},
{Title: Question}]
But the output I get is this:
[{Title:Question },
{Title: Question},
{Title: Question}]
This line:
nyCourt.Title = OldArr[i]
writes to the Title property on the nyCourt object (which is an array object), repeatedly in the loop. The last assignment wins.
But given what you've said you want your output to be, your code is over-complex. You only need one loop:
var nyCourt = [];
var oldArr = [Buy, String, Question];
for (var i = 0; i < oldArr.length; i++) {
nyCourt.push({Title: oldArr[i] });
}
Live Example (use Chrome or something else modern) | Source
Or as this is Node so we know we have map:
var oldArr = [Buy, String, Question];
var nyCourt = oldArr.map(function(entry) {
return {Title: entry};
});
Live Example | Source
//this give the output you want
tableLength = 3;
nyCourt = [];
oldArr = ['Buy', 'String', 'Question'];
for (var t = 0; t < oldArr.length; t++) {
nyCourt.push({Title: oldArr[t]});
};
console.log(nyCourt);
place that push function inside the loop also change the code like this
for (var t = 0; t < tableLength; t++) {
for (var i = 0; i < OldArr.length; i++) {
nyCourt.push({"Title": oldArr[t]});
}
};

Categories