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

时间:2016-10-21 19:28:44

标签: javascript arrays performance functional-programming

假设,我们有:

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

预期结果是['firstname','age', 'children', 'fullname']:该数组的所有对象的键的并集:

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

这样做很好,但是,我正在寻求使用直接reduce方法而不是map的方法获得更多性能,我做了以下操作并且失败了。

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

4 个答案:

答案 0 :(得分:3)

您可以使用Setreduce()Object.keys(),无需地图。

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)

答案 1 :(得分:1)

以下是使用通用程序concatflatMap和ES6 Set的解决方案。

它类似于@NenadVracar的解决方案,但使用高阶函数而不是复杂的,一体化的一线实现。这样可以降低转换的复杂性,并且可以更轻松地在程序的其他区域重复使用过程。

并非...传播语法不好,但您也会注意到此解决方案不需要它。

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' ]

答案 2 :(得分:0)

试试这段代码:

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));
        });
}

答案 3 :(得分:0)

出于好奇,我一直在使用不同的方法对你的问题的一些解决方案进行基准测试(减少vs foreach vs set)。看起来Set对于小型阵列表现良好,但对于较大的阵列来说效果非常慢(是最好的解决方案)。

希望它有所帮助。

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");