Trying to create a single combined array of objects from two arrays:
let versions = [
{
version: "1609936394",
},
{
version: "1609936409",
}
]
and
let devices = [
{
download_device: "Box 1",
},
{
download_device: "Box 2",
},
{
download_device: "Box 3",
},
{
download_device: "Box 4",
}
]
The outcome I'm trying to achieve, albeit unsuccessfully, is having a separate entry for each download_device and version number combination, ie.
[
{
download_device: "Box 1",
version: "1609936394"
},
{
download_device: "Box 2",
version: "1609936394"
},
{
download_device: "Box 3",
version: "1609936394"
},
{
download_device: "Box 4",
version: "1609936394"
},
{
download_device: "Box 1",
version: "1609936409"
}...
Any help would be greatly appreciated!
My current solution (only outputs the first version number):
let data = devices.map((d, index) => {
versions.map((v, i) => {
v.device = devices[index].download_device,
d.version = versions[index].version
return v;
})
return d;
})
-
2There's no such thing as a "JSON Object" (or a "JSON array"). Those are all arrays of objects.Andreas– Andreas2021年01月20日 09:15:03 +00:00Commented Jan 20, 2021 at 9:15
-
Can you also provide your attempt(s) (even if they were unsuccessful?)Nick Parsons– Nick Parsons2021年01月20日 09:15:41 +00:00Commented Jan 20, 2021 at 9:15
-
@NickParsons Have added my current attempt to the question.louisnelza– louisnelza2021年01月20日 09:20:23 +00:00Commented Jan 20, 2021 at 9:20
3 Answers 3
The main issue with your approach is that you're trying to access invalid indexes. As your devices array is longer than your versions array, you will reach indexes which don't exist within your versions array, causing an issue when you try and access a property on an index that doesn't exist.
Instead, you can map over your versions array, and for each version map over your devices array (as you want to add the version to all devices). When you map over your devices, you can grab the properties from each device, and spread them into a new object (...obj) using the spread syntax. In this new object, you can also add the current version property. Since the inner .map() will return an array, you can change the outer .map() method to a .flatMap() which will flatten each array returned from the callback into one larger array result:
const versions = [ { version: "1609936394", }, { version: "1609936409", } ];
const devices = [ { download_device: "Box 1", }, { download_device: "Box 2", }, { download_device: "Box 3", }, { download_device: "Box 4", } ];
const res = versions.flatMap(({version}) => devices.map(obj => ({...obj, version})));
console.log(res);
Comments
Build all combinations by first iterate over versions and inside version at each entry iterate over your devices.
build a new Object Literal and push that Object literal to a result array.
let versions = [{
version: "1609936394",
},
{
version: "1609936409",
}
]
let devices = [{
download_device: "Box 1",
},
{
download_device: "Box 2",
},
{
download_device: "Box 3",
},
{
download_device: "Box 4",
}
]
let res = [];
versions.forEach((x) => {
devices.forEach((y) => {
let obj = {
"version": x.version,
"download_device": y.download_device
};
res.push(obj);
});
})
console.log(res);
Comments
You have two arrays of objects. To create a single array that has each element of one with every element in the other.
A general solution that doesn't care about property names iterates over one array and creates copies of the other and combines the properties, e.g.:
let versions = [
{version: "1609936394"},
{version: "1609936409"}
];
let devices = [
{download_device: "Box 1"},
{download_device: "Box 2"},
{download_device: "Box 3"},
{download_device: "Box 4"}
]
// Step by step version
let result1 = versions.reduce((acc, ver) => {
devices.forEach(device => {
// Shallow copy device
let o = {...device};
// Shallow copy ver onto o
Object.assign(o, ver);
// Add to accumulator
acc.push(o);
});
return acc;
}, []);
console.log(result1);
// Concise version
let result2 = versions.reduce((acc, ver) => (
devices.forEach(device => acc.push({...device, ...ver})
), acc), []);
console.log(result2);
Note these are shallow copies, and duplicate properties between the objects being combined aren't handled.