Reputation:
How to map an array of objects to a new array
From some API i get response like that:
[
{
name: line1,
values: [
{ clock: clock1, value: value1 },
{ clock: clock2, value: value2 },
{ clock: clock3, value: value3 },
{ clock: clock4, value: value4 }
]
},
{
name: line2,
values: [
{ clock: clock1, value: value5 },
{ clock: clock2, value: value6 },
{ clock: clock4, value: value7 }
]
},
{
name: line3,
values: [
{ clock: clock1, value: value8 },
{ clock: clock4, value: value9 }
]
},
{
name: line4,
values: [
{ clock: clock1, value: value10 },
{ clock: clock2, value: value11 },
{ clock: clock3, value: value12 },
{ clock: clock4, value: value13 },
{ clock: clock5, value: value14 }
]
}
]
All clock: *
property values are the same between all objects, so clock1
from line1
equal to the clock1
from line2/3/4
. But value properties are not equal.
For my purposes i need to merge values objects from all lines to this new array of objects:
[
{ clock: clock1, line1: value1, line2: value5, line3: value8, line4: value10 },
{ clock: clock2, line1: value2, line2: value6, line3: null, line4: value11 },
{ clock: clock3, line1: value3, line2: null, line3: null, line4: value12 },
{ clock: clock4, line1: value4, line2: value7, line3: value9, line4: value13 },
{ clock: clock5, line1: null, line2: null, line3: null, line4: value14 }
]
Keys in new objects must be the name property from original objects.
Is there any way to doing that thing?
Upvotes: 0
Views: 188
Reputation: 11011
Use forEach
to iterate array and their values and build res
object. First have empty
object to have the default null values.
const convert = (data) => {
const empty = Object.fromEntries(data.map(({name}) => [name, null]));
const res = {};
data.forEach(({ name, values }) => {
values.forEach(({ clock, value }) => {
Object.assign(res[clock] = res[clock] || {...empty}, {
clock,
[name]: value,
});
});
});
return Object.values(res);
};
const data = [
{
name: "line1",
values: [
{ clock: "clock1", value: "value1" },
{ clock: "clock2", value: "value2" },
{ clock: "clock3", value: "value3" },
{ clock: "clock4", value: "value4" },
],
},
{
name: "line2",
values: [
{ clock: "clock1", value: "value5" },
{ clock: "clock2", value: "value6" },
{ clock: "clock4", value: "value7" },
],
},
{
name: "line3",
values: [
{ clock: "clock1", value: "value8" },
{ clock: "clock4", value: "value9" },
],
},
{
name: "line4",
values: [
{ clock: "clock1", value: "value10" },
{ clock: "clock2", value: "value11" },
{ clock: "clock3", value: "value12" },
{ clock: "clock4", value: "value13" },
{ clock: "clock5", value: "value14" },
],
},
];
console.log(convert(data));
Upvotes: 0
Reputation: 1
This one is not optimized, but it works with all data of your format
let width = [];
let depth = [];
let result = [];
data.forEach(d => {
if (width.indexOf(d.name) == -1) {
width.push(d.name);
}
d.values.forEach(v => {
if (depth.indexOf(v.clock) == -1) {
depth.push(v.clock);
}
})
})
depth.forEach(d => {
let temp = {
clock: d
};
width.forEach(w => {
temp[w] = null;
data.forEach(dt => {
if (dt.name == w) {
dt.values.forEach(v => {
if (v.clock == d) {
temp[w] = v.value;
}
})
}
})
})
result.push(temp);
})
console.log(result);
Result
[
{
clock: 'clock1',
line1: 'value1',
line2: 'value5',
line3: 'value8',
line4: 'value10'
},
{
clock: 'clock2',
line1: 'value2',
line2: 'value6',
line3: null,
line4: 'value11'
},
{
clock: 'clock3',
line1: 'value3',
line2: null,
line3: null,
line4: 'value12'
},
{
clock: 'clock4',
line1: 'value4',
line2: 'value7',
line3: 'value9',
line4: 'value13'
},
{
clock: 'clock5',
line1: null,
line2: null,
line3: null,
line4: 'value14'
}
]
Upvotes: 0
Reputation: 603
you can try using a concept called hashing this will bundle your values with respect to clock
value.
var hash = {};
temp1.map((t0)=>{
t0.values.map((t1)=>{
if(hash[t1.clock]){
hash[t1.clock][t0.name] = t1.value
} else {
hash[t1.clock] = {}
hash[t1.clock][t0.name] = t1.value
}
})
})
After you have a hash of values now you can easily change it the way you want so lets say you want change the hash in the object you have mentioned
var clocks = []
for(var key in hash){
var newClockObj = {}
newClockObj['clock'] = key;
for(var clockKey in hash[key]){
newClockObj[clockKey] = hash[key][clockKey];
}
clocks.push(newClockObj)
}
Upvotes: 1
Reputation: 56
I suspect a 2D array of objects would be a lot easier however if you really need to do it this way then you can iterate through the lines and create new keys for each line. In the example below I have called my input array "data". You can also view a live example here
// store the longest set of values in the list as this seems to be what you want the
// object sizes to be.
let maxSize = Math.max.apply(Math, data.map(line => { return line.values.length }))
// create a new list to store the objects we'll create
let newList = [];
// loop through each line and insert it's values with the key corresponding to the line name.
data.forEach(line => {
// loop through the values for this line
for (i=0; i < maxSize; i++) {
// handle case where we need to add more arrays to our list
if (newList.length <= i) newList.push({});
// check if this value exists or if we are just need to append null
if (i < line.values.length) {
newList[i][line.name] = line.values[i][Object.keys(line.values[i])[0]]
} else { newList[i][line.name] = null }
}
});
Upvotes: 1
Reputation: 2458
You can try my code:
let arr = [
{
name: "line1",
values: [
{ clock: "clock1", value: "value1" },
{ clock: "clock2", value: "value2" },
{ clock: "clock3", value: "value3" },
{ clock: "clock4", value: "value4" }
]
},
{
name: "line2",
values: [
{ clock: "clock1", value: "value5" },
{ clock: "clock2", value: "value6" },
{ clock: "clock4", value: "value7" }
]
},
{
name: "line3",
values: [
{ clock: "clock1", value: "value8" },
{ clock: "clock4", value: "value9" }
]
},
{
name: "line4",
values: [
{ clock: "clock1", value: "value10" },
{ clock: "clock2", value: "value11" },
{ clock: "clock3", value: "value12" },
{ clock: "clock4", value: "value13" },
{ clock: "clock5", value: "value14" },
]
}
],
data = []
for (let i = 1; i <= 5; i++) {
let obj = { clock: "clock" + i}
arr.map((line) => {
let clock = line.values.find(v => v.clock == "clock" + i)
obj[line.name] = clock ? clock.value : null
})
data.push(obj)
}
console.log(data)
Upvotes: 3