Given the following arrays:
var ids = [1,2,3]; //Hundreds of elements here
var names = ["john","doe","foo"]; //Hundreds of elements here
var countries = ["AU","USA,"USA"]; //Hundreds of elements here
What's the best way performance-wise to generate an array of objects with a similar structure to this:
var items = [
{id:1,name:"john",country:"AU"},
{id:2,name:"doe",country:"USA"},
...
];
You should be able to simply map through all ids, keeping a reference to your index, and build your object based on that index.
var items = ids.map((id, index) => {
return {
id: id,
name: names[index],
country: countries[index]
}
});
This is what I get when run the code:
[
{ country=AU, name=john, id=1.0 },
{ name=doe, country=USA, id=2.0 },
{ id=3.0, country=USA, name=foo }
]
Following is the code, same as #Zack Tanner
function arrs2Obj() {
var ids = [1, 2, 3]; //Hundreds of elements here
var names = ["john", "doe", "foo"]; //Hundreds of elements here
var countries = ["AU", "USA", "USA"]; //Hundreds of elements here
var items = ids.map((id, index) => {
return {
id: id,
name: names[index],
country: countries[index]
}
});
Logger.log(items)
}
The problem is, this result is not sorted as the questioner asked. I mean it's not consistent - ids to be the first item, name second, country 3rd; this way it is more presentable.
Related
I'm trying to collate some data. I would like to populate an array containing sub arrays, for example, I have some json data that I am iterating over:
{
"name": "name1",
"prices": "209.67"
},
{
"name": "name1",
"prices": "350"
},
{
"name": "name2",
"price": "195.97"
},
I would like to create an array that ends up looking something like the following:
myArray['name1']prices[0] = 209.67,
prices[1] = 350,
['name2']prices[0] = 195.97
I thought that the code below would achieve what I wanted but it doesn't work. It throws an exception. It doesn't seem to recognise the fact that the prices are an array for a given index into the main array. Instead the prices appear at the same level as the names. I want the main array for a given name to contain an inner array of prices.. Does anybody have any idea how I could modify to make this work?
function doStuff() {
var cryptoData = getData();
var datasetValues = {};
datasetValues.names = [];
datasetValues.names.prices = [];
for (var result = 0; result < cryptoData.length; result++) {
var data = cryptoData[result];
if (datasetValues.names.indexOf(data.cryptoname) === -1)
{
datasetValues.names.push(data.cryptoname);
}
// This works
//datasetValues.names.prices.push(data.prices);
// This doesn't!
datasetValues.cryptoNames[data.cryptoname].prices.push(data.prices);
}
}
You could reduce the array by using an object and take a default object if the property is not set. Then push the price.
var data = [{ name: "name1", price: "209.67" }, { name: "name1", price: "350" }, { name: "name2", price: "195.97" }],
result = data.reduce((r, { name, price }) => {
r[name] = r[name] || { name, prices: [] };
r[name].prices.push(+price);
return r;
}, Object.create(null));
console.log(result);
Try this
function parseData(input){
return input.reduce(function(o,i){
o[i.name] = {};
if(!o[i.name]['prices']){
o[i.name]['prices'] = [];
}
o[i.name]['prices'].push(i.prices);
return o;
},{});
}
Given the following arrays:
var ids = [1,2,3]; //Hundreds of elements here
var names = ["john","doe","foo"]; //Hundreds of elements here
var countries = ["AU","USA,"USA"]; //Hundreds of elements here
What's the best way performance-wise to generate an array of objects with a similar structure to this:
var items = [
{id:1,name:"john",country:"AU"},
{id:2,name:"doe",country:"USA"},
...
];
You should be able to simply map through all ids, keeping a reference to your index, and build your object based on that index.
var items = ids.map((id, index) => {
return {
id: id,
name: names[index],
country: countries[index]
}
});
This is what I get when run the code:
[
{ country=AU, name=john, id=1.0 },
{ name=doe, country=USA, id=2.0 },
{ id=3.0, country=USA, name=foo }
]
Following is the code, same as #Zack Tanner
function arrs2Obj() {
var ids = [1, 2, 3]; //Hundreds of elements here
var names = ["john", "doe", "foo"]; //Hundreds of elements here
var countries = ["AU", "USA", "USA"]; //Hundreds of elements here
var items = ids.map((id, index) => {
return {
id: id,
name: names[index],
country: countries[index]
}
});
Logger.log(items)
}
The problem is, this result is not sorted as the questioner asked. I mean it's not consistent - ids to be the first item, name second, country 3rd; this way it is more presentable.
So I thought of using map(),but I'm stuck. I want to return arr2 but want to prompt the user whether there's changes or not by comparing it with arr. with below's approach, I got id of undefined if arr2 have any missing item.
https://jsfiddle.net/b13rbjyv/
var arr = [{
id: 1,
name: 'something'
}, {
id: 2,
name: 'something2'
}]
var arr2 = [{
id: 1,
name: 'something'
}, {
id: 2,
name: 'something2'
}]
var result = arr.map(function(obj, i) {
if (obj.id == arr2[i].id) {
return obj;
}
})
document.write(JSON.stringify(result))
you need to use filter
var result = arr.filter(function(obj, i) {
return obj.id == arr2[i].id;
})
map should be used if you want to change object for instance if you need to have array of id only then you should use it. For example if you want to get list of ids then
var result = arr
.filter(function(obj, i) { return obj.id == arr2[i].id; })
.map(function(obj){return obj.id;});
map returns an element for every given element of an array. It looks like what you need is actually to use filter. Perhaps something like this:
var result = arr.filter((elem, index) => elem.id === arr2[index].id);
Essentially, I want to implement the following:
var categories = [];
var products = // some array of product objects
products.map(function(value) {
if(categories.indexOf(value.Category === -1)) categories.push(value.Category);
});
As result, categories array contains unique list of product categories.
I feel that there should be a better way to do it, but nothing comes to mind.
If there isn't then probably there is no point to use map() in the first place. I could do as simple as
var categories = [];
var products = // some array of product objects
for (var i = 0; i < products.length; i++) {
if(categories.indexOf(products[i].Category === -1)) categories.push(products[i].Category);
}
UPDATE for those who insist it's a duplicate of "how to make an array unique" question. I saw that post, and for my situation I don't think it applies. I don't have an array of values that I need to make unique. I have an array of objects and I need to build an array of unique values. The difference might be subtle - but to get to the use case of that topic I would build a non-unique array and then make it unique. Seems even worse than my original solution
you can use reduce instead of map
var products = [{Category:'vegetable', price: 1}, {Category:'fruits', price: 2}];
var categories = products.reduce(function(sum, product) {
if(sum.indexOf(product.Category) === -1){
sum.push(product.Category);
}
return sum;
}, []);
Update: A solution with Array.prototype.reduce()
var products = [{ Name: 'milk', price: 2.50, Category: 'groceries' }, { Name: 'shirt', price: 10, Category: 'clothing' }, { Name: 'apples', price: 5, Category: 'groceries' }],
categories = products.reduce(function (r, a) {
if (!~r.indexOf(a.Category)) {
r.push(a.Category);
}
return r;
}, []);
document.write('<pre>' + JSON.stringify(categories, 0, 4) + '</pre>');
map all the values of the object categories out first, then use filter to dispose of the duplicates.
var products = [
{ category: 'A' },
{ category: 'B' },
{ category: 'A' },
{ category: 'D' }
];
var categories = products.map(function (e) {
return e.category;
}).filter(function (e, i, a) {
return a.indexOf(e) === i;
}); // [ "A", "B", "D" ]
DEMO
Follow the Below SO Answer:
How to get distinct values from an array of objects in JavaScript?
var flags = [], output = [], l = array.length, i;
for( i=0; i<l; i++) {
if( flags[array[i].age]) continue;
flags[array[i].age] = true;
output.push(array[i].age);
}
Lets say I have the two following arrays
[{
name: "one"
},
{
name: "two" //need an array containing this
}
];
[{
name: "one"
}];
How would I filter the first array to contain only the elements NOT listed in the second using lodash?
Try this
var second = [{name: "one"}, {name: "two"}];
var first = [{name: "one"}];
first = _.pluck(first, 'name'); // get all names - ['one']
second = _.filter(second, function (el) {
return _.indexOf(first, el.name) === -1; // search every name in first array
});
Example