I have two arrays of same length
ids = [123, 456, 789, ...., 999];
names = ['foo', 'bar', ... , 'zzz'];
I want to create an array like
[ {id: 123, name: 'foo'}, {id: 123, name: 'bar'}, ..., {id: 999, name: 'zzz'} ]
I am trying to avoid forEach if possible.
Any suggestions?
Is map okay?
ids = [123, 456, 789, 999];
names = ['foo', 'bar', 'baz', 'zzz'];
result = ids.map(function(_, i) {
return {id: ids[i], name: names[i]}
});
console.log(result)
If you don't want to use any higher-order functions, then just do this:
var objects = [];
for (var i = 0; i < ids.length; i++) {
objects.push({id: ids[i], name: names[i]});
}
No need for forEach here. Use map which is similar to forEach.
var ids = [123, 456, 999];
var names = ['foo', 'bar', 'zzz'];
var result = ids.map(function (currentId, index) {
return {
id: currentId,
name: names[index]
};
});
console.log(result);
The forEach version would look like this (notice how similar they are):
var ids = [123, 456, 999];
var names = ['foo', 'bar', 'zzz'];
var result = [];
ids.forEach(function(currentId, index) {
result.push({
id: currentId,
name: names[index]
});
});
console.log(result);
The below code uses foreach but you dont need to handle it. I hope this will work for you.
ids = [123, 456, 789, 999];
names = ['foo', 'bar', 'zab', 'zzz'];
result = ids.map(function(_, i) {
return {id: ids[i], name: names[i]}
});
console.log(result)
Related
How would you go about splitting an array at the word 'split' and creating smaller sub arrays out of them?
This is what my array looks like right now (but much longer):
const myArray = ['abc', 'xyz', 123, 'split', 'efg', 'hij', 456, 'split'];
This is what I would like it to look like:
const newArray =[['abc', 'xyz', 123], ['efg', 'hij', 456]];
If it helps at all I also have the indexes of the words 'split' in an array like this:
const splitIndex = [3, 7];
You could iterate splitIndex and slice the array until this index.
const
data = ['abc', 'xyz', 123, 'split', 'efg', 'hij', 456, 'split'],
splitIndex = [3, 7],
result = [];
let i = 0;
for (const j of splitIndex) {
result.push(data.slice(i, j));
i = j + 1;
}
console.log(result);
const myArr = ['abc', 'xyz', 123, 'split', 'efg', 'hij', 456, 'split'];
const foo = (arr, key) => {
let temp = [];
const result = [];
arr.forEach(v => {
if (v !== key) {
temp.push(v);
} else {
result.push(temp);
temp = [];
}
})
return result;
}
console.log(foo(myArr, 'split'));
output:
[ [ 'abc', 'xyz', 123 ], [ 'efg', 'hij', 456 ] ]
I am getting unexpected results from my below program. Both inputs and outputs arrays are getting same value. Somehow from this I got to know that it's the problem of passing a reference. My question is how can I achieve the same with below approach. Appreciate your time.
Expecting inputs array to be [[{id: 1, name: 'foo'}, {id: 2, name: 'bar'}], [{id: 1, name: 'foo'}]]
var inputs = [];
var outputs = [];
var exampleArr = [{id: 1, name: 'foo'}, {id: 2, name: 'bar'}];
function analyze(listArr) {
inputs.push(...listArr);
outputs = [...outputs, ...listArr];
outputs.forEach((item) => {
item.name = 'hello';
});
console.log('inputs', inputs);
console.log('ouputs', outputs);
listArr.pop();
if(listArr.length) analyze(listArr);
}
analyze(exampleArr);
Clone all objects in listArr (one nesting level only) before appending to outputs.
var inputs = [];
var outputs = [];
var exampleArr = [{id: 1, name: 'foo'}, {id: 2, name: 'bar'}];
function analyze(listArr) {
inputs.push(...listArr);
// clone objects in array, one level
outputs = [...outputs, ...listArr.map(x=>typeof x==='object'? {...x}:x)];
outputs.forEach((item) => {
item.name = 'hello';
});
console.log('inputs', inputs);
console.log('ouputs', outputs);
listArr.pop();
if(listArr.length) analyze(listArr);
}
analyze(exampleArr);
I can't be able to figure out how to push items to same nested array like :
var arr = ['foo', 'bar', 'buz', 'hello'];
// It should be now look like this:
const output = {name: 'foo', children: [
{name: 'bar', children: [
{name: 'buz', children: [
{name: 'hello', children: []}
]}
]}
]};
Using reduce:
const arr = ['foo', 'bar', 'buz', 'hello'];
const result = arr.reverse().reduce((acc, val) => ({name: val, children: [acc]}), {});
console.log(result);
You can use reduceRight to create the output.
var arr = ['foo', 'bar', 'buz', 'hello'],
result = arr.reduceRight((r, name) => ({name, children: (!Object.keys(r).length ? [] : [r])}), {});
console.log(result);
Using a recursive function:
const arr = ['foo', 'bar', 'buz', 'hello'];
const f = (arr) => ({name: arr.shift(), children: arr.length ? [f(arr)] : []});
const output = f(arr);
console.log(output);
Using a recursive function
function nested (arr) {
if (arr.length === 1)
return { name: arr.shift(), children: [] };
else if (arr.length > 1)
return { name: arr.shift(), children: [nested(arr)] };
}
var array = ['foo', 'bar', 'buz', 'hello']
console.log(nested(array))
I now have an idea on how Array.reduce() method work, so posted another answer without recursive approach. I think it would be better for large tree structure.
The basic idea is that simply reverse the input array and then wrap the innermost object into another and so on.
let arr = ['foo', 'bar', 'buz', 'hello'];
function nest(arr) {
arr = arr.reverse();
let out = [];
arr.forEach(it => {
if(out.length === 0) out = {name: it, children: []}
else {
out = {name: it, children: [out]}
}
});
return out;
}
I have 4 arrays of the following format
arr1 = ['Hello', 'World', 'Hi']
arr2 = ['1', '2', '3']
arr3 = ['foo', 'bar', 'foobar']
arr4 = ['10', '20', '30']
I am trying to add each value at index[i] to a new object, the object looks like this
obj = {
title: '',
score: '',
description: '',
value: '',
}
For each indexed value in the array I would like to push it to a new instance of the obj object so I can end up with this
objects = [
{
title: 'Hello',
score: '1',
description: 'foo',
value: '10',
},
{
title: 'World',
score: '2',
description: 'bar',
value: '20',
},
{
title: 'Hi',
score: '3',
description: 'foobar',
value: '30',
}
]
So far I have been trying something like
objects = []
arr1.forEach((key, i) => objects[key] = arr2[i])
But that is assigning them as arr1val : arr2val
I will ultimately be setting this to state in my react app and passing it to another component as props to render on the page. The data is coming in from 3 different APIs, I am doing this to try and standardise the data received from each API so my component can use the data to render an articles list and user can switch between feeds.
Map by the index of element across all arrays, also use map not forEach:
const objects = arr1.map((element, index) => (
{title: element, score: arr2[index], description: arr3[index], value: arr4[index]}
))
Live demo is below:
const arr1 = ['Hello', 'World', 'Hi']
const arr2 = ['1', '2', '3']
const arr3 = ['foo', 'bar', 'foobar']
const arr4 = ['10', '20', '30']
const objects = arr1.map((element, index) => (
{title: element, score: arr2[index], description: arr3[index], value: arr4[index]}
))
console.log(objects)
This code also works:
var arr = [];
for(var i=0; i<arr1.length; i++) {
arr[i] = {};
arr[i].title = arr1[i];
arr[i].score = arr2[i];
arr[i].description = arr3[i];
arr[i].value = arr4[i];
}
I suggest to use an array of arrays and another array for the keys. This allows an arbitrary count of arrays and keys to use for transforming the data into an array of objects with hte wanted properties.
var array1 = ['Hello', 'World', 'Hi'],
array2 = ['1', '2', '3'],
array3 = ['foo', 'bar', 'foobar'],
array4 = ['10', '20', '30'],
keys = ['title', 'score', 'description', 'value'],
result = [array1, array2, array3, array4].reduce(function (r, a, i) {
a.forEach(function (v, j) {
r[j] = r[j] || {};
r[j][keys[i]] = v;
});
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you don't want to type the property names twice,
you could do like this:
const descriptor = {
title: arr1,
score: arr2,
description: arr3,
value: arr4
};
const objects = arr1.map((tmp, i) => {
var o = {};
Object.keys(descriptor).forEach(name => o[name] = descriptor[name][i]);
return o;
});
A reducer method would be in place I suppose
const arr1 = ['Hello', 'World', 'Hi', 'Hello2', 'World2', 'Hi2'];
const arr2 = ['1', '2', '3', '11', '22', '33'];
const arr3 = ['foo', 'bar', 'foobar', 'sea', 'shell', 'sea weed'];
const arr4 = ['10', '20', '30', '100', '200', '300'];
const arrays2Objects = arr1.reduce( (obj, next, i) =>
obj.concat({title: next, score: arr2[i], description: arr3[i], value: arr4[i]}),
[]
);
console.log(arrays2Objects);
Suppose I have this data:
var id = 81;
var categories = [1, 2, 3, 4, 5];
How do I transform this into:
[{id: 81, category: 1}, {id: 81, category: 2}, {id: 81, category: 3}, {id: 81, category: 4}, {id: 81, category: 5}]
Is there an elegant way to do this using underscore or lodash?
No need for libraries here.
const result = categories.map(x => ({ id, category: x }))
Working Example JSBin
var id = 81;
var categories = [1, 2, 3, 4, 5];
var arr = [];
for (var i = 0; i < categories.length; i++) {
arr.push({id: id, category: categories[i]});
}
Or:
var a = categories.map(function(a) {
return {id: id, category: a};
});
You don't need any library, just good, old Vanilla JS.
var newArray = categories.map(function(item) {
return {id: id, cetegory: item}
});
Using Lo-Dash/Underscore, the code would be:
var result = _.map(categories, x => ({ id, category: x }));
But this is actually longer than the pure JS solution (from Роман Парадеев):
var result = categories.map(x => ({ id, category: x }));