我将如何改变它?
How would I transform this?
我想为以下转换找到一个很好的优雅解决方案。如何以最简单的方式(可选地使用功能库 Ramda)最好地实现这一点?
const data = [
{
id: 'a',
},
{
id: 'b',
routes: [
{
id: 'c',
},
{
id: 'd',
routes: [
{
id: 'e',
}
]
}
]
}
];
const expected = [
{
id: 'a',
},
{
id: 'b',
},
{
id: 'c',
},
{
id: 'd',
},
{
id: 'e',
}
];
这是一个普通的 JS 解决方案,使用 reduce
和递归:
const data = [
{
id: 'a',
},
{
id: 'b',
routes: [
{
id: 'c',
},
{
id: 'd',
routes: [
{
id: 'e',
}
]
}
]
}
];
const transform = arr => arr.reduce((a, { id, routes }) => (
[...a, { id }, ...transform(routes || [])]
), []);
console.log(transform(data));
或者,您可以简单地推送到现有数组,而不是每次都创建新数组:
const data = [{
id: 'a',
},
{
id: 'b',
routes: [{
id: 'c',
},
{
id: 'd',
routes: [{
id: 'e',
}]
}
]
}
];
const transform = (arr, pushTo = []) => arr.reduce((a, { id, routes }) => {
a.push({ id });
if (routes) transform(routes, a);
return a;
}, pushTo);
console.log(transform(data));
使用变量嵌套 属性 而不是 routes
硬编码:
const data = [{
id: 'a',
},
{
id: 'b',
routes: [{
id: 'c',
},
{
id: 'd',
routes: [{
id: 'e',
}]
}
]
}
];
const transform = (arr, prop, pushTo = []) => arr.reduce((a, item) => {
const nested = item[prop];
a.push({ id: item.id });
if (nested) transform(nested, prop, a);
return a;
}, pushTo);
console.log(transform(data, 'routes'));
没有过多传播的JS解决方案
function getFlat(array = []) {
return array.reduce((r, { id, routes }) => r.concat({ id }, getFlat(routes)), []);
}
const data = [{ id: 'a', }, { id: 'b', routes: [{ id: 'c', }, { id: 'd', routes: [{ id: 'e', }] }] }];
console.log(getFlat(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
使用对象的剩余参数获取对象的所有属性,return 除外 routes
。
function getFlat(array = []) {
return array.reduce((r, { routes, ...o }) => r.concat(o, getFlat(routes)), []);
}
const data = [{ id: 'a', foo: 1 }, { id: 'b', routes: [{ id: 'c' }, { id: 'd', routes: [{ id: 'e', bar: 2 }] }] }];
console.log(getFlat(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
此处其他建议的替代方法是使用 R.chain
展平每组嵌套路由。
const fn = R.chain(({routes = [], ...rest}) => [{...rest}, ...fn(routes)])
一旦 Array.prototype.flatMap
变得可用,这种方法也可以通过普通 JS 实现。
const fn = (xs = []) => xs.flatMap(({routes, ...rest}) => [{...rest}, ...fn(routes)])
我想为以下转换找到一个很好的优雅解决方案。如何以最简单的方式(可选地使用功能库 Ramda)最好地实现这一点?
const data = [
{
id: 'a',
},
{
id: 'b',
routes: [
{
id: 'c',
},
{
id: 'd',
routes: [
{
id: 'e',
}
]
}
]
}
];
const expected = [
{
id: 'a',
},
{
id: 'b',
},
{
id: 'c',
},
{
id: 'd',
},
{
id: 'e',
}
];
这是一个普通的 JS 解决方案,使用 reduce
和递归:
const data = [
{
id: 'a',
},
{
id: 'b',
routes: [
{
id: 'c',
},
{
id: 'd',
routes: [
{
id: 'e',
}
]
}
]
}
];
const transform = arr => arr.reduce((a, { id, routes }) => (
[...a, { id }, ...transform(routes || [])]
), []);
console.log(transform(data));
或者,您可以简单地推送到现有数组,而不是每次都创建新数组:
const data = [{
id: 'a',
},
{
id: 'b',
routes: [{
id: 'c',
},
{
id: 'd',
routes: [{
id: 'e',
}]
}
]
}
];
const transform = (arr, pushTo = []) => arr.reduce((a, { id, routes }) => {
a.push({ id });
if (routes) transform(routes, a);
return a;
}, pushTo);
console.log(transform(data));
使用变量嵌套 属性 而不是 routes
硬编码:
const data = [{
id: 'a',
},
{
id: 'b',
routes: [{
id: 'c',
},
{
id: 'd',
routes: [{
id: 'e',
}]
}
]
}
];
const transform = (arr, prop, pushTo = []) => arr.reduce((a, item) => {
const nested = item[prop];
a.push({ id: item.id });
if (nested) transform(nested, prop, a);
return a;
}, pushTo);
console.log(transform(data, 'routes'));
没有过多传播的JS解决方案
function getFlat(array = []) {
return array.reduce((r, { id, routes }) => r.concat({ id }, getFlat(routes)), []);
}
const data = [{ id: 'a', }, { id: 'b', routes: [{ id: 'c', }, { id: 'd', routes: [{ id: 'e', }] }] }];
console.log(getFlat(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
使用对象的剩余参数获取对象的所有属性,return 除外 routes
。
function getFlat(array = []) {
return array.reduce((r, { routes, ...o }) => r.concat(o, getFlat(routes)), []);
}
const data = [{ id: 'a', foo: 1 }, { id: 'b', routes: [{ id: 'c' }, { id: 'd', routes: [{ id: 'e', bar: 2 }] }] }];
console.log(getFlat(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
此处其他建议的替代方法是使用 R.chain
展平每组嵌套路由。
const fn = R.chain(({routes = [], ...rest}) => [{...rest}, ...fn(routes)])
一旦 Array.prototype.flatMap
变得可用,这种方法也可以通过普通 JS 实现。
const fn = (xs = []) => xs.flatMap(({routes, ...rest}) => [{...rest}, ...fn(routes)])