1

I've been scratching my head for a long time with this one, even tough it feels like an easy task. I have an array with a set of objects. The array looks like this:

[ { key1: 'ok', key2: 'ok', key3: '--' },
  { key1: 'ok', key2: '--', key3: 'ok' },
  { key1: 'ok', key2: 'ok', key3: '--' } ]

I want a function that compares the objects, and returns the key that has all "ok" as it's value. In this case, I'd like it to return

key1

I've been watching Compare objects in an array for inspiration, but it just doesn't do it.

Do anyone have any suggestions? Would be a life saver

1
  • 2
    If you can use ES6: arr.reduce((s, o) => (Object.keys(o).filter(k => o[k] !== 'ok').forEach(k => s.delete(k)), s), new Set(Object.keys(arr[0]))); jsfiddle.net/qemuyf3f/1 Commented Feb 3, 2017 at 22:22

4 Answers 4

2

You could iterate the array and filter the keys.

var array = [{ key1: 'ok', key2: 'ok', key3: '--' }, { key1: 'ok', key2: '--', key3: 'ok' }, { key1: 'ok', key2: 'ok', key3: '--' }],
    result = array.reduce(function (r, o) {
        return r.filter(function (k) {
            return o[k] === 'ok';
        });    
    }, Object.keys(array[0]));

console.log(result);

ES6

var array = [{ key1: 'ok', key2: 'ok', key3: '--' }, { key1: 'ok', key2: '--', key3: 'ok' }, { key1: 'ok', key2: 'ok', key3: '--' }],
    result = array.reduce((r, o) => r.filter(k => o[k] === 'ok'), Object.keys(array[0]));

console.log(result);

Sign up to request clarification or add additional context in comments.

2 Comments

Interesting approach @Nina! Would not have thought of starting with the full list and filtering out as you iterate...
@rasmeister, it is not necessary the full list, but anyway it performs an and operation over at least the key which are common and have the wanted value.
1

Most likely not the shortest solution, but should be easy to follow..

var obj = [ { key1: 'ok', key2: 'ok', key3: '--' },
  { key1: 'ok', key2: '--', key3: 'ok' },
  { key1: 'ok', key2: 'ok', key3: '--' } ];

var keycount = {};

obj.forEach((o) => {
  Object.keys(o).forEach((key) => {
    if (o[key] === 'ok') 
      keycount[key] = (keycount[key] || 0) + 1;
  });
});
Object.keys(keycount).forEach((key) => {
  if (keycount[key] === obj.length) 
    console.log(`Found ${key}`);
});

Comments

1

Assuming all objects have identical keys:

  for (var key in arr[0]){
     var allok = true;
     for (var i = 0; i < arr.length; i++){
        if (arr[i][key] !== "ok") {
           allok = false;
           break;
        }
     }
     if (allok) {console.log(key);}
  }

1 Comment

Same here,. Try making into a working snippet.. It's actually easier than using a code block, just press the <> button..
1

Here's what I would do:

var objs = [ { key1: 'ok', key2: 'ok', key3: '--' },
  { key1: 'ok', key2: '--', key3: 'ok' },
  { key1: 'ok', key2: 'ok', key3: '--' } ];

var getOkKeys = function(objs) {
  return Object.keys(objs[0]).reduce(function(results, key) {
    if (objs.every(function(obj) { return (obj[key] === 'ok'); })) {
      results.push(key);
    }
    return results;
  }, []);
};

console.log(getOkKeys(objs));

As requested, a function that returns the keys - getOkKeys().

2 Comments

Nice solution,.. To make things a little nicer, in the future try making into a working snippet.. It's the <> symbol.. I've done it here for you this time.
Thanks @Keith. Good advice

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.