4

If I have an array of objects like this:

var mountains = [
    { name: 'Kebnekaise', elevation: 2106 },
    { name: 'Mount Ngauruhoe', elevation: 2291, comment: 'aka Mount Doom' }
];

How to get all unique keys i.e. ['name', 'elevation', 'comment']?

7
  • What have you tried? Are you sure its performance is a problem? How often are you doing this that it has to be the most performant way? Commented Mar 8, 2016 at 23:32
  • "Most performant" is too broad and depends on specific cases. Fix your question. Commented Mar 8, 2016 at 23:33
  • 1
    I would simply loop through the array, then loop through the keys of the object, and add them as keys to a result object. Then use Object.keys(result) to get the list of unique keys. Commented Mar 8, 2016 at 23:33
  • Changed the question to not include the performance part. Better? Commented Mar 8, 2016 at 23:41
  • 1
    @Amit I like your ES2015 answer better than I could like any Underscore answer :) Commented Mar 8, 2016 at 23:52

3 Answers 3

11

In ECMAScript 2015, it's really simple:

let mountains = [
  { name: 'Kebnekaise', elevation: 2106 },
  { name: 'Mount Ngauruhoe', elevation: 2291, comment: 'aka Mount Doom' }
];

let uniqueKeys = Object.keys(Object.assign({}, ...mountains));
Sign up to request clarification or add additional context in comments.

Comments

2

Using ES6, one could do

var unique = new Set([].concat.apply([],mountains.map(Object.keys)))

Without ES6, something like

var unique = [].concat.apply([],mountains.map(Object.keys)).filter(function(value,i,arr) {
    return arr.indexOf(value) === i;
});

3 Comments

@Amit - I'm guessing it was because yours is neater, but getting an array of all keys and creating a Set from them, still works fine, it's just a little longer and not as readable as using a spread and Object.assign
I really hope whoever down voted had a better reason. An answer isn't good or bad as a function of other answers.
Also wonder why it got a downvote. Great to see a minimal none es6 solution as well.
1

You could iterate over the array of objects and iterate over each element's keys with Object.keys(obj), adding them to a hash to avoid duplicates:

function getKeySet (data) {
  var keys = {};

  data.forEach(function (datum) {
    Object.keys(datum).forEach(function (key) {
      keys[key] = true;
    });
  });

  return Object.keys(keys);
}

Alternately you could add all the keys to an array and filter out duplicates. Either way this will be O(nm) where n is the number of elements in the array and m is the average number of keys.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.