Array push behavior - javascript

Although I have some basic JavaScript background, I stumbled upon this code that I wrote:
var data=[{"_id":"57b3e7ec9b209674f1459f36","fName":"Tom","lName":"Moody","email":"Tom#example.com","age":30},{"_id":"57b3e8079b209674f1459f37","fName":"Pat","lName":"Smith","email":"pat#example.com","age":32},{"_id":"57b3e8209b209674f1459f38","fName":"Sam","lName":"Dawn","email":"sam#example.com","age":28},{"_id":"57b3e8219b209674f1459f39","fName":"Sam","lName":"Dawn","email":"sam#example.com","age":28}]
var tempArr=[];
var table=[];
var dataArr = Object.keys(data).map(function(k) { return data[k] });
dataArr.forEach(function(user) {
tempArr[0]=user.fName;
tempArr[1]=user.lName;
tempArr[2]=user.email;
tempArr[3]=user.age;
table.push(tempArr);
console.log('table'+JSON.stringify(table));
});
In the final loop, I expected table to contain the arrays for Tom, Pat, and Sam . Instead, this is what I got:
table[["Tom","Moody","Tom#example.com",30]]
table[["Pat","Smith","pat#example.com",32],["Pat","Smith","pat#example.com",32]]
table[["Sam","Dawn","sam#example.com",28],["Sam","Dawn","sam#example.com",28],["Sam","Dawn","sam#example.com",28]]
table[["Sam","Dawn","sam#example.com",28],["Sam","Dawn","sam#example.com",28],["Sam","Dawn","sam#example.com",28],["Sam","Dawn","sam#example.com",28]]
Why is push() replacing the previous entry in table? Any help will be highly appreciated.

The others already pointed out problems in your code.
However, you also make things more complicated than necessary. You can just do this:
var data=[{"_id":"57b3e7ec9b209674f1459f36","fName":"Tom","lName":"Moody","email":"Tom#example.com","age":30},{"_id":"57b3e8079b209674f1459f37","fName":"Pat","lName":"Smith","email":"pat#example.com","age":32},{"_id":"57b3e8209b209674f1459f38","fName":"Sam","lName":"Dawn","email":"sam#example.com","age":28},{"_id":"57b3e8219b209674f1459f39","fName":"Sam","lName":"Dawn","email":"sam#example.com","age":28}];
var table = data.map(function(user) {
return [
user.fName,
user.lName,
user.email,
user.age,
];
});
console.log(table);
Or if you use ES6:
var table = data.map(user => [ user.fName, user.lName, user.email, user.age ];

You don't need to write all the boilerplate code by hand. Use a proper array iterator (map in your case).
var table = data.map(function(user) {
return [user.fName, user.lName, user.email, user.age];
});

Obviously map isthe way to go for the sake of functional approach however if you like imperative styles one simplistic way could be using for of loop as follows.
var data = [{"_id":"57b3e7ec9b209674f1459f36","fName":"Tom","lName":"Moody","email":"Tom#example.com","age":30},{"_id":"57b3e8079b209674f1459f37","fName":"Pat","lName":"Smith","email":"pat#example.com","age":32},{"_id":"57b3e8209b209674f1459f38","fName":"Sam","lName":"Dawn","email":"sam#example.com","age":28},{"_id":"57b3e8219b209674f1459f39","fName":"Sam","lName":"Dawn","email":"sam#example.com","age":28}],
table = [];
for (var user of data) table.push([user.fName,user.lName,user.email,user.age]);
console.log(table);

Problem here is not with push. Variable in javascript store reference to array. And in table you are pushing reference to same array tempArr. You need to create new array before pushing it or create deep copy of array before pushing it.
Example
var data=[{"_id":"57b3e7ec9b209674f1459f36","fName":"Tom","lName":"Moody","email":"Tom#example.com","age":30},{"_id":"57b3e8079b209674f1459f37","fName":"Pat","lName":"Smith","email":"pat#example.com","age":32},{"_id":"57b3e8209b209674f1459f38","fName":"Sam","lName":"Dawn","email":"sam#example.com","age":28},{"_id":"57b3e8219b209674f1459f39","fName":"Sam","lName":"Dawn","email":"sam#example.com","age":28}]
var table=[];
var dataArr = Object.keys(data).map(function(k) { return data[k] });
dataArr.forEach(function(user) {
var tempArr=[];
tempArr[0]=user.fName;
tempArr[1]=user.lName;
tempArr[2]=user.email;
tempArr[3]=user.age;
table.push(tempArr);
console.log('table'+JSON.stringify(table));
});

Well, unlike a lot of other languages, JavaScript has passes everything by reference. That means that when you table.push(tempArr);, you're not actually pushing the values of tempArr, you're pushing a reference to tempArr. So, if you do this:
var a = 'a';
var table = [];
table.push(a);
a = 'b';
console.log(table[0]);
You'll get b as your output. What you want to do is define a new variable to push, like this
var data=[{"_id":"57b3e7ec9b209674f1459f36","fName":"Tom","lName":"Moody","email":"Tom#example.com","age":30},{"_id":"57b3e8079b209674f1459f37","fName":"Pat","lName":"Smith","email":"pat#example.com","age":32},{"_id":"57b3e8209b209674f1459f38","fName":"Sam","lName":"Dawn","email":"sam#example.com","age":28},{"_id":"57b3e8219b209674f1459f39","fName":"Sam","lName":"Dawn","email":"sam#example.com","age":28}]
var table=[];
var dataArr = Object.keys(data).map(function(k) { return data[k] });
dataArr.forEach(function(user) {
var tempArr=[];
tempArr[0]=user.fName;
tempArr[1]=user.lName;
tempArr[2]=user.email;
tempArr[3]=user.age;
table.push(tempArr);
});
console.log('table'+JSON.stringify(table));

var data = [{"_id": "57b3e7ec9b209674f1459f36","fName": "Tom","lName": "Moody","email": "Tom#example.com","age": 30}, {"_id": "57b3e8079b209674f1459f37","fName": "Pat","lName": "Smith","email": "pat#example.com","age": 32}, {"_id": "57b3e8209b209674f1459f38","fName": "Sam","lName": "Dawn","email": "sam#example.com","age": 28}, {"_id": "57b3e8219b209674f1459f39","fName": "Sam","lName": "Dawn","email": "sam#example.com","age": 28}],
table = [];
data.forEach(function(user) {
table.push([user.fName, user.lName, user.email, user.age]);
});
console.log(table);

Related

How to get name and values from a javascript object into a new list?

I have this JavaScript object which is a collection of multiple lists(I believe). I need to create a select dropdown with the name being the name of the list, and a number of boxes with background color as per that name. Like this:
I am able to parse that object to get all the names of the colors, but I can't find a way to parse the names and the list of values it holds. This is how I tried :
var
YlGn3 = ['#f7fcb9', '#addd8e', '#31a354'],
YlGn4 = ['#ffffcc', '#c2e699', '#78c679', '#238443'],
YlGn5 = ['#ffffcc', '#c2e699', '#78c679', '#31a354', '#006837'];
var brewer = Object.freeze({
YlGn3: YlGn3,
YlGn4: YlGn4
});
var office = Object.freeze({
YlGn5: YlGn5
});
var colorschemes = {
brewer: brewer,
office: office
};
var scheme_list = [];
for (i in colorschemes){
for(j in colorschemes[i]){
console.log(j);
scheme_list.push(j);
}
}
I was thinking of creating a new object and append every color, along with the list of colors, so I can parse it again to create an option element with it. But, I am not able to figure out the best way to do that. Is this the correct approach ?
You use Object.values along with forEach multiple times.
Object.values(colorschemes).forEach(obj=>Object.entries(obj).forEach(([name,colors])=>{
const arr = [];
colors.forEach(color=>arr.push(color));
scheme_list.push([name, arr]);
}));
var
YlGn3 = ['#f7fcb9', '#addd8e', '#31a354'],
YlGn4 = ['#ffffcc', '#c2e699', '#78c679', '#238443'],
YlGn5 = ['#ffffcc', '#c2e699', '#78c679', '#31a354', '#006837'];
var brewer = Object.freeze({
YlGn3: YlGn3,
YlGn4: YlGn4
});
var office = Object.freeze({
YlGn5: YlGn5
});
var colorschemes = {
brewer: brewer,
office: office
};
var scheme_list = [];
Object.values(colorschemes).forEach(obj=>Object.entries(obj).forEach(([name,colors])=>{
const arr = [];
colors.forEach(color=>arr.push(color));
scheme_list.push([name, arr]);
}));
console.log(scheme_list);

Can't get data from JavaScript array

I have this code
var obj = [];
$('#next').click(function(){
jQuery.getJSON(produk1 , function(product1) {
hargana1 = product1.price;
obj.push({
harga: hargana1
});
}
jQuery.getJSON(produk2 , function(product1) {
hargana2 = product2.price;
obj.push({
harga: hargana2
});
}
console.log(harga)
});
And I have result on my console like this
How can I get value from harga?
I try with obj['harga'] It shows undefined
Well if you take a closer look then you will see that this is actually an array filled with objects. you can see that its an array by the brackets []
Try it like this: obj[0].harga
You should iterate through the array :
const out = [{harga:21132424},{harga:543535}]
console.log(out)
out.forEach(obj=>{
const harga = obj.harga;
//do something to harga here
console.log(harga)
})

Group by in javascript or angularjs

I just want to do sum value column based on the Year and my data is below, but I don't know how to do this either using angular(in script) or javascript.
[
{"Year":2013,"Product":"A","Value":0},
{"Year":2013,"Product":"B","Value":20},
{"Year":2013,"Product":"A","Value":50},
{"Year":2014,"Product":"D","Value":55},
{"Year":2014,"Product":"M","Value":23},
{"Year":2015,"Product":"D","Value":73},
{"Year":2015,"Product":"A","Value":52},
{"Year":2016,"Product":"B","Value":65},
{"Year":2016,"Product":"A","Value":88}
]
I want to perform the sum on Value column and remove Product column as well.
Thanks
Edit As commenters have pointed out, this doesn't even require Lodash. Been using Lodash so much for current project I forgot reduce is built in. :-)
Also updated to put data in desired form [{"yyyy" : xxxx},...].
This code will accomplish this:
var data = [{"Year":2013,"Product":"A","Value":0},{"Year":2013,"Product":"B","Value":20},{"Year":2013,"Product":"A","Value":50},{"Year":2014,"Product":"D","Value":55},{"Year":2014,"Product":"M","Value":23},{"Year":2015,"Product":"D","Value":73},{"Year":2015,"Product":"A","Value":52},{"Year":2016,"Product":"B","Value":65},{"Year":2016,"Product":"A","Value":88}];
var sum = data.reduce(function(res, product){
if(!(product.Year in res)){
res[product.Year] = product.Value;
}else{
res[product.Year] += product.Value;
}
return res;
}, {});
result = [];
for(year in sum){
var tmp = {};
tmp[year] = sum[year];
result.push(tmp);
}
console.log(result);
RESULT:
[{"2013" : 70}, {"2014" : 78}, {"2015" : 125}, {"2016" : 153}]
ORIGINAL ANSWER
The easiest way I can think of to do this is with the Lodash Library. It gives you some nice functional programming abilities like reduce, which basically applies a function to each element of an array or collection one by one and accumulates the result.
In this case, if you use Lodash, you can accomplish this as follows:
var data = [{"Year":2013,"Product":"A","Value":0},{"Year":2013,"Product":"B","Value":20},{"Year":2013,"Product":"A","Value":50},{"Year":2014,"Product":"D","Value":55},{"Year":2014,"Product":"M","Value":23},{"Year":2015,"Product":"D","Value":73},{"Year":2015,"Product":"A","Value":52},{"Year":2016,"Product":"B","Value":65},{"Year":2016,"Product":"A","Value":88}];
result = _.reduce(data, function(res, product){
if(!(product.Year in res)){
res[product.Year] = product.Value;
}else{
res[product.Year] += product.Value;
}
return res;
}, {});
This yields:
{
"2013": 70,
"2014": 78,
"2015": 125,
"2016": 153
}
Basically, what we're telling Lodash is that we want to go through all the elements in data one by one, performing some operation on each of them. We're going to save the results of this operation in a variable called res. Initially, res is just an empty object because we haven't done anything. As Lodash looks at each element, it checks if that Product's year is in res. If it is, we just add the Value to that year in res. If it's not, we set that Year in res to the Value of the current product. This way we add up all the product values for each year.
If you want to try it out you can do it here:
Online Lodash Tester
Cheers!
You could do this using plain JavaScript. We use an object that will hold the results and the forEach array method. The object that would hold the results would have as keys the years and as values the sums of the corresponding values.
var data = [
{"Year":2013,"Product":"A","Value":0},
{"Year":2013,"Product":"B","Value":20},
{"Year":2013,"Product":"A","Value":50},
{"Year":2014,"Product":"D","Value":55},
{"Year":2014,"Product":"M","Value":23},
{"Year":2015,"Product":"D","Value":73},
{"Year":2015,"Product":"A","Value":52},
{"Year":2016,"Product":"B","Value":65},
{"Year":2016,"Product":"A","Value":88}
];
groupedData = {};
data.forEach(function(item){
var year = item.Year;
var value = item.Value;
if(groupedData.hasOwnProperty(year)){
groupedData[year]+=value;
}else{
groupedData[year]=value;
}
});
console.log(groupedData);

Javascript array parsing

var usersRows = [];
connection.query('SELECT * from users', function(err, rows, fields) {
if (!err) {
rows.forEach(function(row) {
usersRows.push(row);
});
console.log(usersRows);
}
else {
console.log('Error while performing Query.' + err);
}
});
It returned to me:
var usersRows = [ [ RowDataPacket { id: 1, name: 'sall brwon', number: '+99999999\r\n' } ] ];
I need to parse this and remove rowdatapacket; I need result like this:
userRows = { id: 1, name: 'my name is', number: '+999999\r\n' };
If you need to get rid of RowDataPacket's array and save it in yours you can also use this:
usersRows = JSON.parse(JSON.stringify(results));
Have you tried
userRows = RowDataPacket;
You might want to try JSON.stringify(rows)
Was unable to understand and implement the accepted the answer.
Hence, tried the long way out according the results I was getting.
Am using "mysql": "2.13.0" and saw that the this library returned array of array out of which:
Index 0 had array of RowDataPackets
Index 1 had other mysql related information.
Please find the code below:
var userDataList = [];
//Get only the rowdatapackets array which is at position 0
var usersRows = data[0];
//Loop around the data and parse as required
for (var i = 0; i < usersRows.length; i++) {
var userData = {};
//Parse the data if required else just
userData.name = userRows.firstName + userRows.lastName;
userDataList.push(userData);
}
If no parsing is required and you just want the data as is, you could use the solution like mentioned in link How do I loop through or enumerate a JavaScript object?
Have not tried it but could be tweaked and worked out.
There should be simpler way to do it but as a novice I found the above way server the purpose. Do comment in case of better solution.
RowDataPacket is the class name of the object that contains the fields.
The console.log() result [ [ RowDataPacket { id: 1, name: 'sall brwon', number: '+99999999\r\n' } ] ] should be read as "an array of one item, containing and array of one item, containing an object of class RowDataPacket with fields id, name, and number"

Pushing objects in an array only returns last object pushed

I am working on YUI DataTables, to populate the data table i want to send the columns and their values dynamically from outside, for that i have written the following code:
<html>
<script src="http://yui.yahooapis.com/3.17.2/build/yui/yui-min.js"></script>
<div class="example yui3-skin-sam" id="simple"> <!-- You need this skin class -->
</div>
<script>
var cols = ["id", "name", "price"];
var obj = {
id: "",
name: "",
price: ""
};
var data2 = new Array();
obj.id = "ga";
obj.name = "gadget";
obj.price = "$6.99";
data2.push(obj);
obj.id = "ga2";
obj.name = "gadget2";
obj.price = "$7.99";
data2.push(obj);
obj.id = "ga3";
obj.name = "gadget3";
obj.price = "$8.99";
data2.push(obj);
YUI().use("datatable", function (Y) {
// A table from data with keys that work fine as column names
var simple = new Y.DataTable({
columns: cols,
data : data2,
summary: "Price sheet for inventory parts",
caption: "Example table with simple columns"
});
simple.render("#simple");
});
</script>
</html>
now the problem is that, it shows only the last obj pushed in data2.. kindly tell me why its not displaying all three objs. the resulting table from this code is
id name price
ga3 gadget3 $8.99
Not sure if this is relevant anymore but if people still come here looking for an easy solution...
Just stringify the object and JSON.parse it again to copy it instead of referencing the object like so;
data2.push(JSON.parse(JSON.stringify(obj)));
it will give all array values
function obj(id, name, price) {
this.id = id;
this.name = name;
this.price = price;
}
var array = new Array();
var point = new obj("ga", "gadget", "$6.99");
array.push(point);
var point = new obj("ga2", "gadget2", "$7.9");
array.push(point);
Both answers above (2480125, 2480125) will work, but they require that you manually input the new object's properties for every new object added to the array.
You can avoid that inflexibility with a for..in loop (docs):
var newObj = function(object) {
var newObject = {};
for (var key in object) {
if (object.hasOwnProperty(key)) {
newObject[key] = object[key];
}
}
return newObject;
};
var obj = {
id: 'foo',
name: 'gadget',
price: '$6.99'
};
data2 = [];
data2.push( newObj(obj) );
obj.id = 'bar';
obj.name = 'baz';
obj.price = '$4.44';
data2.push( newObj(obj) );
console.log(data2);
data2.forEach(function(item){
console.log("%s, %s, %s", item.id, item.name, item.price);
});
// data2 now contains two distinct objects, rather than one object reference added to the array twice.
JSFiddle for above code
Objects are reference objects.
obj.id = "ga";
obj.name = "gadget";
obj.price = "$6.99";
data2.push(obj);
obj.id = "ga2";
obj.name = "gadget2";
obj.price = "$7.99";
data2.push(obj);
This means that when you update the obj the second time, you're actually updating all references to that object.
If you examine your data2 array you'll see that it has 3 elements and that all elements are the same.
try updating your code to something like this
data2.push({
id : "ga",
name : "gadget",
price : "$6.99"
});
data2.push{(
id : "ga2",
name : "gadget2",
price : "$7.99"
)};
data2.push({
id : "ga3",
name : "gadget3",
price : "$8.99"
});
None of these answers worked for me, and I can't explain why it worked, but adding a character value to the element I was pushing inline was the only way I could get it to work properly. I tried the suggestions of creating new objects or even just creating new variables and pushing either the new object or new variables but to no avail, it just kept rewriting each element of the array whenever it would push a new element such that the entire array would be the final value of the loop each time. So in the end this is what I had to do to get it to work:
var returnArray = [];
while(...){
returnArray.push('' + obj.value);
}

Categories

Resources