I want to convert the following data structure:
const data = [
{
regions: ['United States', 'Canada']
},
{
regions: ['United States']
},
{
prop1: {
regions: ['Canada']
}
},
{
prop2: [
{
regions: ['Mexico', 'United States'],
prop3: {
regions: ['Canada']
}
}
]
}
];
into the following data structure:
['United States', 'Canada', 'United States', 'Canada', 'Mexico', 'United States', 'Canada']
I'm looking to do this with ES6 using .reduce
and .map
recursively to be safe.
This is what i've tried so far but it only goes 2 levels deep:
export const flattenArray = (arr: Object[], prop: string): any[] =>
arr.reduce(
(a, c) => [
...new Set([
...a,
...c.map(x => x[prop]).reduce((y, z) => [...y, ...z.map(j => j)], []),
]),
],
[]
);
UPDATE: I've wen't with @deterjan and his solution below. Incase anyone needs a non .flat
version this is his solution in a single function with .reduce
export const flatten = (obj: any, prop: string): any[] => [
...new Set(
Object.keys(obj).reduce((a, c) => {
if (c === prop) {
if (isArray(obj[prop])) {
return [...a, ...obj[c]];
} else {
return [...a, obj[c]];
}
} else if (isArray(obj[c])) {
return [
...a,
...obj[c].reduce((a, c) => [...a, ...flatten(c, prop)], []),
];
} else if (isObject(obj)) {
return [...a, ...flatten(obj[c], prop)];
} else {
return a;
}
}, [])
),
];
console.log(flatten(data, 'regions'));