4
\$\begingroup\$

My objective is to make an array of unique keys from a list of objects.

Example:

Input:

var input = [{"a":1, "b":2}, {"a":3, "c":4}, {"a":5}]

Output:

[ "a", "b", "c" ]

Current approach:

var outputObj={};
input.map( function( obj ) {  
    Object.keys( obj ).map( function(key) { 
        outputObj[key] = 1;
    })  
});
// output obj is now { a : 1, b: 1, c: 1 }
var output = Object.keys( outputObj );

This works, but it just smells funny, partly because the map function is relying on side-effects. Is there a better way to do this?

In Java, I would create a java.util.Set and simply add all keys to it.

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

You could clean it up a bit by using reduce and forEach instead of map (especially as you don't need map's return value, but are just using it as an iterator)

function uniqueKeys(objects) {
  var keys = objects.reduce(function (collector, obj) {
    Object.keys(obj).forEach(function (key) {
      collector[key] = true;
    });
    return collector;
  }, {});
  return Object.keys(keys);
}

Alternatively, you could combine all the objects, and then use Object.keys on the result. Just be careful, as extend-type functions usually work on the passed objects directly (as the one below does), rather than returning a new object, so pass an empty object to use as collector:

function extend(target, source) {
  var key;
  for(key in source) {
    target[key] = source[key];
  }
  return target;
}

function uniqueKeys(objects) {
  var combined = objects.reduce(function (target, obj) {
    extend(target, obj);
    return target;
  }, {});
  return Object.keys(combined);
}

If you've got an extend function that takes an arbitrary number of arguments, you could do something like

function uniqueKeys(objects) {
  var collector = {};
  extend.apply(null, [collector].concat(objects));
  return Object.keys(collector);
}

Here are demos of each one

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.