展平 javascript 对象数组
Posted
技术标签:
【中文标题】展平 javascript 对象数组【英文标题】:flatten javascript array of objects 【发布时间】:2018-02-24 20:51:28 【问题描述】:我有一个具有层次结构的对象数组,如下所示:
[
name: 'ParentOne', children: [
name: 'ParentOneChildOne',
name: 'ParentOneChildTwo', children: [
name: 'ParentOneChildTwoGrandChildOne',
],
],
name: 'ParentTwo', children: [
name: 'ParentTwoChildOne', children: [
name: 'ParentTwoChildOneGrandChildOne',
name: 'ParentTwoChildOneGrandChildTwo'
],
name: 'ParentTwoChildTwo'
]
];
我想把它弄平:
[
name: 'ParentOne',
name: 'ParentOneChildOne',
name: 'ParentOneChildTwo',
name: 'ParentOneChildTwoGrandChildOne',
name: 'ParentTwo',
name: 'ParentTwoChildOne',
name: 'ParentTwoChildOneGrandChildOne',
name: 'ParentTwoChildOneGrandChildTwo',
name: 'ParentTwoChildTwo'
]
我已经尝试过_.flatten()
和_.flatMap()
,但它不能产生我需要的东西。最好使用 lodash.js 或 underscore.js 实现它的最佳方法是什么。
【问题讨论】:
【参考方案1】:不需要下划线/lodash。
const arr = [
name: 'ParentOne', children: [
name: 'ParentOneChildOne',
name: 'ParentOneChildTwo', children: [
name: 'ParentOneChildTwoGrandChildOne',
],
],
name: 'ParentTwo', children: [
name: 'ParentTwoChildOne', children: [
name: 'ParentTwoChildOneGrandChildOne',
name: 'ParentTwoChildOneGrandChildTwo'
],
name: 'ParentTwoChildTwo'
]
];
function flatten(arr)
return arr? arr.reduce((result, item) => [
...result,
name: item.name ,
...flatten(item.children)
], []) : [];
console.log(flatten(arr));
【讨论】:
【参考方案2】:我会使用.reduce
和递归来做到这一点。这是我使用 Array.reduce 的实现,但你可以使用下划线的 reduce 函数做很多相同的事情。
const arr = [
name: 'ParentOne', children: [
name: 'ParentOneChildOne',
name: 'ParentOneChildTwo', children: [
name: 'ParentOneChildTwoGrandChildOne',
],
],
name: 'ParentTwo', children: [
name: 'ParentTwoChildOne', children: [
name: 'ParentTwoChildOneGrandChildOne',
name: 'ParentTwoChildOneGrandChildTwo'
],
name: 'ParentTwoChildTwo'
]
];
function flatten(arr)
return arr.reduce((result, current) =>
if (current.children)
const children = flatten(current.children);
delete current.children;
result.push(current);
result.push(...children);
else
result.push(current);
return result;
, [])
console.log(flatten(arr));
【讨论】:
【参考方案3】:您可以尝试调整this answer 中给出的flatten
函数,并将逻辑稍微扭曲到对象的结构。
//Your object
var data = [
name: 'ParentOne',
children: [
name: 'ParentOneChildOne'
,
name: 'ParentOneChildTwo',
children: [
name: 'ParentOneChildTwoGrandChildOne'
, ]
,
]
,
name: 'ParentTwo',
children: [
name: 'ParentTwoChildOne',
children: [
name: 'ParentTwoChildOneGrandChildOne'
,
name: 'ParentTwoChildOneGrandChildTwo'
]
,
name: 'ParentTwoChildTwo'
]
];
//georg's flatten function
flatten = function(x, result, prefix)
if (_.isObject(x))
_.each(x, function(v, k)
flatten(v, result, prefix ? prefix + '_' + k : k)
)
else
result[prefix] = x
return result
//using the function on your data
result = flatten(data, );
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
这有帮助吗?
【讨论】:
【参考方案4】:递归函数适用于任何深度的迭代。
带有一些 ES2015 和 LoDash/Underscore
var arr = [
name: 'ParentOne',
children: [
name: 'ParentOneChildOne'
,
name: 'ParentOneChildTwo',
children: [
name: 'ParentOneChildTwoGrandChildOne'
, ]
, ]
,
name: 'ParentTwo',
children: [
name: 'ParentTwoChildOne',
children: [
name: 'ParentTwoChildOneGrandChildOne'
,
name: 'ParentTwoChildOneGrandChildTwo'
]
,
name: 'ParentTwoChildTwo'
]
];
var res = _.reduce(arr, (a, b) =>
(rec = item =>
_.each(item, (v, k) => (_.isObject(v) ? rec(v) : a.push(_.zipObject([k], [v]))))
)(b);
return a;
, []);
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
【讨论】:
【参考方案5】:您可以使用一些破坏并使用递归函数来收集所有想要的项目。
var array = [ name: 'ParentOne', children: [ name: 'ParentOneChildOne' , name: 'ParentOneChildTwo', children: [ name: 'ParentOneChildTwoGrandChildOne' ,] ,] , name: 'ParentTwo', children: [ name: 'ParentTwoChildOne', children: [ name: 'ParentTwoChildOneGrandChildOne' , name: 'ParentTwoChildOneGrandChildTwo' ] , name: 'ParentTwoChildTwo' ] ],
flat = (r, name, children = [] ) => [...r, name , ...children.reduce(flat, []) ],
result = array.reduce(flat, []);
console.log(result);
.as-console-wrapper max-height: 100% !important; top: 0;
在 EDGE 上,您需要使用不同的默认值。
var array = [ name: 'ParentOne', children: [ name: 'ParentOneChildOne' , name: 'ParentOneChildTwo', children: [ name: 'ParentOneChildTwoGrandChildOne' ,] ,] , name: 'ParentTwo', children: [ name: 'ParentTwoChildOne', children: [ name: 'ParentTwoChildOneGrandChildOne' , name: 'ParentTwoChildOneGrandChildTwo' ] , name: 'ParentTwoChildTwo' ] ],
flat = (r, name, children ) => [...r, name , ...(children || []).reduce(flat, []) ],
result = array.reduce(flat, []);
console.log(result);
.as-console-wrapper max-height: 100% !important; top: 0;
【讨论】:
以上是关于展平 javascript 对象数组的主要内容,如果未能解决你的问题,请参考以下文章