最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Get union of keys of all objects in js array using reduce - Stack Overflow

programmeradmin1浏览0评论

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:

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.

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

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:

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.

all.reduce((a,b) =>Object.assign([...Object.keys(a),...Object.keys(b)]),[])
Share Improve this question edited Oct 22, 2016 at 1:12 Abdennour TOUMI asked Oct 21, 2016 at 19:28 Abdennour TOUMIAbdennour TOUMI 93.8k42 gold badges268 silver badges269 bronze badges 1
  • 1 Probably better posted on codereview but Object.keys(Object.assign({}, ...all)) is one option. I have no idea about performance. – user1106925 Commented Oct 21, 2016 at 19:34
Add a ment  | 

4 Answers 4

Reset to default 5

You can use Set, reduce() and Object.keys() there is no need for 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.

It's similar to @NenadVracar's solution but uses higher-order functions instead of a plex, do-it-all-in-one-line implementation. This reduces plexity 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' ]

Just out of curiosity, I've been benchmarking some solutions to your problem using different approaches (reduce 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).

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

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));
        });
}
发布评论

评论列表(0)

  1. 暂无评论