i'm trying to filter an array of objects and return a single object, organised by the keys continents
, countries
and cities
and we place those objects in the correct key.
const data = [{
location: [{
name: 'Africa',
type: 'Continent'
},
{
name: 'Angola',
type: 'Country'
},
{
name: 'Luanda',
type: 'City'
}
],
values: []
}, {
location: [{
name: 'Europe',
type: 'Continent'
},
{
name: 'Italy',
type: 'Country'
},
{
name: 'Rome',
type: 'City'
}
],
values: []
}, {
location: [{
name: 'Europe',
type: 'Continent'
},
{
name: 'Spain',
type: 'Country'
},
{
name: 'Valencia',
type: 'City'
}
],
values: []
}]
It should result in:
{
Africa: {
countries: {
Angola: {
cities: {
Luanda: {
values: []
}
}
}
}
},
Europe: {
countries: {
Italy: {
cities: {
Rome: {
values: []
}
}
},
Spain: {
cities: {
Valencia: {
values: []
}
}
}
}
}
}
I've tried to filter by its keys but when it comes to placing the objects in the right place (eg by same Continent) I couldn't get it working.
const result = data.reduce((acc, total) => {
const continentFilter = total.location.find(s => s.type === 'Continent')
acc[continentFilter.name] = {
// ...
}
return acc
}, {})
console.log(result)
// {
// Africa: { ... },
// Europe: { ... }
// }
UPDATE:
Continent
, then by Country
and City
You could take an array for the nested properties which are not given by the location arrays (maybe there could be the key instead of unused type
).
Then iterate the array and create a nested structure. At the end apply the values.
For unsorted location sort it in advance.
const data = [{ location: [{ name: 'Angola', type: 'Country' }, { name: 'Luanda', type: 'City' }, { name: 'Africa', type: 'Continent' }], values: [] }, { location: [{ name: 'Europe', type: 'Continent' }, { name: 'Italy', type: 'Country' }, { name: 'Rome', type: 'City' }], values: [] }, { location: [{ name: 'Europe',type: 'Continent' }, { name: 'Spain', type: 'Country' }, { name: 'Valencia', type: 'City' }], values: [] }]; levels = ['countries', 'cities'], result = data.reduce((r, { location, values }) => { const order = { Continent: 1, Country: 2, City: 3 }, temp = location.sort((a, b) => order[a.type] - order[b.type]).reduce((o, { name }, i) => { o[name]??= {}; return levels[i]? (o[name][levels[i]]??= {}): o[name]; }, r); (temp.values??= []).push(...values); return r; }, {}); console.log(result);
.as-console-wrapper { max-height: 100%;important: top; 0; }
Here's a working example. I'm sure it can be improved.
const data = [{ location: [{ name: 'Africa', type: 'Continent' }, { name: 'Angola', type: 'Country' }, { name: 'Luanda', type: 'City' } ], values: [] }, { location: [{ name: 'Europe', type: 'Continent' }, { name: 'Italy', type: 'Country' }, { name: 'Rome', type: 'City' } ], values: [] }, { location: [{ name: 'Europe', type: 'Continent' }, { name: 'Spain', type: 'Country' }, { name: 'Valencia', type: 'City' } ], values: [] }]; function countryDataToStructuredObject(data){ let countryData = { }; data.map(a => { countryData[a.location.find(x => x.type == 'Continent').name] = {}; countryData[a.location.find(x => x.type == 'Continent').name]['countries'] = {}; countryData[a.location.find(x => x.type == 'Continent').name]['countries'][a.location.find(x => x.type == 'Country').name] = {}; countryData[a.location.find(x => x.type == 'Continent').name]['countries'][a.location.find(x => x.type == 'Country').name]['cities'] = {}; countryData[a.location.find(x => x.type == 'Continent').name]['countries'][a.location.find(x => x.type == 'Country').name]['cities'][a.location.find(x => x.type == 'City').name] = { values: a.values }; }); return countryData; } console.log(countryDataToStructuredObject(data));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.