Given the input array.
let data = [
{
name: 'Name',
countries: [
{
name: 'Country1',
competitions: [
{
name: 'Competition1',
matches: [
{ details: 'details' },
{ details: 'details' },
{ details: 'details' }
]
},
{
name: 'Competition2',
matches: [{ details: 'details' }]
}
]
},
{
name: 'Country2',
competitions: [
{
name: 'Competition1',
matches: [{ details: 'details' }]
},
{
name: 'Competition2',
matches: [{ details: 'details' }]
},
{
name: 'Competition3',
matches: [{ details: 'details' }, { detals: 'detail' }]
}
]
}
]
},
{
name: 'Name2',
countries: [
{
name: 'Country1',
competitions: [
{
name: 'Competition1',
matches: [{ details: 'details' }, { details: 'details' }]
}
]
}
]
}
];
And desired output:
let sorted = [
// For each Object in orginal array extract all matches and put it in new array.
{ name: 'Name', matches: [{}, {}, {}, {}, {}, {}, {}, {}] },
{ name: 'Name2', matches: [{}, {}] }
]
How can I transform data into sorted I can use nested 3 nested for loops and extract all matches into single array. But it does not give me desired output and I feel that nesting for loops is bad for resources and I'm certain that it can be done more concisely and after all I do not get expected output. I tried Object.assign creating new objects at starts etc etc.
Using for loop to get arr to store all matches from whole data array like so.
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].countries.length; j++) {
for (var l = 0; l < data[i].countries[j].competitions.length; l++) {
for (
var k = 0;
k < data[i].countries[j].competitions[l].matches.length;
k++
) {
arr.push(data[i].countries[j].competitions[l].matches[k]);
}
}
}
Is eyesore, and still leaves me with flat array of all matches which are no good.
Using ES6 and new goodies I manage to get closer to solution but leaves me with nested array of arrays that I can not seem to flatten.
const d = data.map(i => {
const inter = i.countries.map(e => e.competitions.map(z => z.matches));
const final = inter.reduce((acc, next) => [...acc, ...next], []);
return {
name: i.name,
matches: final
};
})
For educational purposes all solutions will be accepted no matter the performance at this point.
tl;dr How to transform data into sorted
3 Answers 3
const sorted = data.map(o => {
const name = o.name;
let matches = [];
o.countries.map(c => {
return c.competitions.forEach(c => {
c.matches.forEach(m => {
matches.push(m);
});
});
});
return { name, matches };
});
Instead of using map, I created matches array, and while looping through every matches array from object, I'm just pushing the results into array. Here's a snippet:
let data = [
{
name: 'Name',
countries: [
{
name: 'Country1',
competitions: [
{
name: 'Competition1',
matches: [
{ details: 'details' },
{ details: 'details' },
{ details: 'details' }
]
},
{
name: 'Competition2',
matches: [{ details: 'details' }]
}
]
},
{
name: 'Country2',
competitions: [
{
name: 'Competition1',
matches: [{ details: 'details' }]
},
{
name: 'Competition2',
matches: [{ details: 'details' }]
},
{
name: 'Competition3',
matches: [{ details: 'details' }, { detals: 'detail' }]
}
]
}
]
}
];
const sorted = data.map(o => {
const name = o.name;
let matches = [];
o.countries.map(c => {
return c.competitions.forEach(c => {
c.matches.forEach(m => {
matches.push(m);
});
});
});
return { name, matches };
});
console.log(sorted);
3 Comments
forEach and pushing into array. Next time you will remember it too, i guarantee! :)You can to use reduce and just concat the matches
let result = data.map(v=>{
let inter = v.countries.reduce((c,v)=> c.concat( v.competitions.map(z => z.matches).reduce((x,z) => x.concat( z ),[] ) ),[]);
return {
name : v.name,
matches : inter
}
});
Here is a snippet:
let data = [{
name: 'Name',
countries: [{
name: 'Country1',
competitions: [{
name: 'Competition1',
matches: [{
details: 'details'
},
{
details: 'details'
},
{
details: 'details'
}
]
},
{
name: 'Competition2',
matches: [{
details: 'details'
}]
}
]
},
{
name: 'Country2',
competitions: [{
name: 'Competition1',
matches: [{
details: 'details'
}]
},
{
name: 'Competition2',
matches: [{
details: 'details'
}]
},
{
name: 'Competition3',
matches: [{
details: 'details'
}, {
detals: 'detail'
}]
}
]
},
]
},
{
name: 'Name2',
countries: [{
name: 'Country1',
competitions: [{
name: 'Competition1',
matches: [{
details: 'details'
},
{
details: 'details'
},
{
details: 'details'
}
]
},
{
name: 'Competition2',
matches: [{
details: 'details'
}]
}
]
}, ]
}
];
let result = data.map(v => {
let inter = v.countries.reduce((c, v) => c.concat(v.competitions.map(z => z.matches).reduce((x, z) => x.concat(z), [])), []);
return {
name: v.name,
matches: inter
}
});
console.log(result);
Comments
Might be easier to filter during parsing:
let sorted = [], last = [], json = '[{"name":"Name","countries":[{"name":"Country1","competitions":[{"name":"Competition1","matches":[{"details":"details1"},{"details":"details2"},{"details":"details3"}]},{"name":"Competition2","matches":[{"details":"details4"}]}]},{"name":"Country2","competitions":[{"name":"Competition1","matches":[{"details":"details5"}]},{"name":"Competition2","matches":[{"details":"details6"}]},{"name":"Competition3","matches":[{"details":"details7"},{"detals":"detail8"}]}]}]},{"name":"Name2","countries":[{"name":"Country1","competitions":[{"name":"Competition1","matches":[{"details":"details9"},{"details":"details10"}]}]}]}]'
JSON.parse(json, (k, v) => k === 'details' ? last.push(v) :
v.countries !== void 0 ? (sorted.push({ name: v.name, matches: last }), last = []) : 0)
console.log( sorted )
datagives me syntax error, can you fix it?name: 'Name2'is inside countries array ofName1is it correct?datasource my bad.