简体   繁体   English

使用reduce获取js数组中所有对象的键的并集

[英]Get union of keys of all objects in js array using reduce

Assume , we have : 假设,我们有:

var all=[
    {firstname:'Ahmed', age:12},
    {firstname:'Saleh', children:5 }
    {fullname: 'Xod BOD', children: 1}
];

The expected result is ['firstname','age', 'children', 'fullname'] : the union of keys of all objects of that array: 预期的结果是['firstname','age', 'children', 'fullname'] :该数组所有对象的键的并集:

all.map((e) => Object.keys(e) ).reduce((a,b)=>[...a,...b],[]); 

This is work fine , However, i am seeking a solution more performance using directly reduce method without map , I did the following and it is failed. 这工作正常,但是,我正在寻求一个解决方案更多性能使用直接reduce方法没有map ,我做了以下,它失败了。

all.reduce((a,b) =>Object.assign([...Object.keys(a),...Object.keys(b)]),[])

You can use Set , reduce() and Object.keys() there is no need for map. 你可以使用Setreduce()Object.keys() ,不需要map。

 var all=[ {firstname:'Ahmed', age:12}, {firstname:'Saleh', children:5 }, {fullname: 'Xod BOD', children: 1} ]; var result = [...new Set(all.reduce((r, e) => [...r, ...Object.keys(e)], []))]; console.log(result) 

Here's a solution using generic procedures concat , flatMap , and the ES6 Set . 这是使用通用过程concatflatMap和ES6 Set的解决方案。

It's similar to @NenadVracar's solution but uses higher-order functions instead of a complex, do-it-all-in-one-line implementation. 它类似于@NenadVracar的解决方案,但使用高阶函数而不是复杂的,一体化的一线实现。 This reduces complexity in your transformation and makes it easier to re-use procedures in other areas of your program. 这样可以降低转换的复杂性,并且可以更轻松地在程序的其他区域重用过程。

Not that ... spread syntax is bad, but you'll also notice this solution does not necessitate it. 不是...传播语法很糟糕,但你也会注意到这个解决方案不需要它。

 var all = [ {firstname:'Ahmed', age:12}, {firstname:'Saleh', children:5 }, {fullname: 'Xod BOD', children: 1} ]; const concat = (x,y) => x.concat(y); const flatMap = f => xs => xs.map(f).reduce(concat, []); const unionKeys = xs => Array.from(new Set(flatMap (Object.keys) (xs))); console.log(unionKeys(all)); // [ 'firstname', 'age', 'children', 'fullname' ] 

Try this code: 试试这段代码:

var union = new Set(getKeys(all));

console.log(union);
// if you need it to be array
console.log(Array.from(union));

//returns the keys of the objects inside the collection
function getKeys(collection) {
    return collection.reduce(
        function(union, current) {
            if(!(union instanceof Array)) {
                union = Object.keys(union);
            }
            return union.concat(Object.keys(current));
        });
}

Just out of curiosity, I've been benchmarking some solutions to your problem using different approaches (reduce vs foreach vs set). 出于好奇,我一直在使用不同的方法对问题进行基准测试(减少vs foreach vs set)。 Looks like Set behaves well for small arrays but it's extremely slow for bigger arrays (being the best solution the foreach one). 看起来Set对于小型阵列表现良好,但对于较大的阵列来说它是非常慢的(是最好的解决方案)。

Hope it helps. 希望能帮助到你。

 var all = [{ firstname: 'Ahmed', age: 12 }, { firstname: 'Saleh', children: 5 }, { fullname: 'Xod BOD', children: 1 }], result, res = {}; const concat = (x,y) => x.concat(y); const flatMap = f => xs => xs.map(f).reduce(concat, []); const unionKeys = xs => Array.from(new Set(flatMap (Object.keys) (xs))); for(var i = 0; i < 10; i++) all = all.concat(all); console.time("Reduce"); result = Object.keys(all.reduce((memo, obj) => Object.assign(memo, obj), {})); console.timeEnd("Reduce"); console.time("foreach"); all.forEach(obj => Object.assign(res, obj)); result = Object.keys(res); console.timeEnd("foreach"); console.time("Set"); result = [...new Set(all.reduce((r, e) => r.concat(Object.keys(e)), []))]; console.timeEnd("Set"); console.time("Set2"); result = unionKeys(all); console.timeEnd("Set2"); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM