Reputation: 3
Does anyone know how to group object of arrays to a new array of object arrays based on its index with Javascript? I'm quite new to this so I'm quite stuck here
For example I have this object :
{
'first': [
{
name: 'jimmy',
text: 'I love you'
},
{
name: 'jimmy',
text: 'I miss you!'
},
{
name: 'jimmy',
text: 'I hate you!'
}
],
'second': [
{
name: 'jeremy',
text: 'Wow'
}
],
'third': [
{
name: 'john',
text: 'You ugly'
},
{
name: 'john',
text: 'You handsome'
},
{
name: 'john',
text: 'you beautiful'
}
],
'fourth': [
{
name: 'tom',
text: 'this is cool!'
},
{
name: 'tom',
text: 'this is hard'
}
]
}
which I want to transform to something like :
[
[
{
name: 'jimmy',
text: 'I love you'
},
{
name: 'jeremy',
text: 'Wow'
},
{
name: 'john',
text: 'You ugly'
},
{
name: 'tom',
text: 'this is cool!'
},
],
[
{
name: 'jimmy',
text: 'I miss you!'
},
{
name: 'john',
text: 'You handsome'
},
{
name: 'tom',
text: 'this is hard'
}
],
[
{
name: 'jimmy',
text: 'I hate you!'
},
{
name: 'john',
text: 'you beautiful'
}
]
]
so 'first'[1],'second'[1], 'third'[1], 'fourth'[1] should group to the first array as array of objects and 'first'[2],'second'[2], 'third'[2], 'fourth'[2] should go to the second array as array of objects and so on..
Upvotes: 0
Views: 47
Reputation: 350365
Here is an approach where you shift from each subarray the next item so to collect the next subarray for the result:
let obj = {'first': [{name: 'jimmy',text: 'I love you'},{name: 'jimmy',text: 'I miss you!'},{name: 'jimmy',text: 'I hate you!'}],'second': [{name: 'jeremy',text: 'Wow'}],'third': [{name: 'john',text: 'You ugly'},{name: 'john',text: 'You handsome'},{name: 'john',text: 'you beautiful'}],'fourth': [{name: 'tom',text: 'this is cool!'},{name: 'tom',text: 'this is hard'}]};
let arr = Object.values(obj),
result = [];
while ((arr = arr.filter(sub => sub.length)).length) {
result.push(arr.map(sub => sub.shift()));
}
console.log(result);
Upvotes: 1
Reputation: 7179
Mushroomator's answer is probably the most concise way to do this.
If you're newer to JavaScript, functional programming, or programming altogether, I think the following is a decent intro-level approach that might be easier to understand.
The underlying logic is the same, the steps have just been made more explicit/more apparent.
output
array that will hold the result.first
, second
, third
, and fourth
arrays from data
by using Object.values()
.for
loop.output
doesn't already have a nested array for the current index, create one.Array#push()
the item in the current array at the current index into the array at the current index in the output
.const data = {
first:[{name:"jimmy",text:"I love you"},{name:"jimmy",text:"I miss you!"},{name:"jimmy",text:"I hate you!"}],
second:[{name:"jeremy",text:"Wow"}],
third:[{name:"john",text:"You ugly"},{name:"john",text:"You handsome"},{name:"john",text:"you beautiful"}],
fourth:[{name:"tom",text:"this is cool!"},{name:"tom",text:"this is hard"}]
};
const output = [];
for (let arr of Object.values(data)) {
for (let i = 0; i < arr.length; i++) {
if (output[i] === undefined) {
output[i] = [];
}
output[i].push(arr[i]);
}
}
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 9198
You can use reduce()
in order to do this.
const input = {
first: [
{
name: "jimmy",
text: "I love you",
},
{
name: "jimmy",
text: "I miss you!",
},
{
name: "jimmy",
text: "I hate you!",
},
],
second: [
{
name: "jeremy",
text: "Wow",
},
],
third: [
{
name: "john",
text: "You ugly",
},
{
name: "john",
text: "You handsome",
},
{
name: "john",
text: "you beautiful",
},
],
fourth: [
{
name: "tom",
text: "this is cool!",
},
{
name: "tom",
text: "this is hard",
},
],
};
const output = Object.values(input).reduce(
(all, cur) => (
cur.forEach((item, idx) =>
idx < all.length ? all[idx].push(item) : (all[idx] = [item])
),
all
),
[]
);
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
First of all, we don't care about the keys of the input
Object, therefore we can use Object.values()
to just obtain the values.
Then, the idea is to start with an empty array all
(second argument of reduce()
) and then loop over the input
.
Then for each element cur
we loop over all the items
of this element and for each of these items
we check whether we have this element's index (idx
) in the all
array already.
If we don't, this index is larger then any of the previously added indices and we need to extend our all
array in order to hold that values. As we expect multiple values for a given spot, we need to use an array as an value for that spot. If we already have at least one value for a given index, we already have an array at the given index and we just need to push()
the new item onto the all
array.
Upvotes: 1