cup_of
cup_of

Reputation: 6687

Get array of keys based on values from another array

Say I have an array of objects that looks like this

let myArray = [
  {item1: true},
  {item2: false},
  {item3: true},
  {item4: false}
]

How would I iterate though this to return a new array of true values that looks like this:

let newArray = ['item1', 'item3']

I found this function but it only returns single items:

function findKey(map, term) {
  var found = [];
  for(var property in map) {
    if(map.hasOwnProperty(property)) {
      for(var key in map[property]) {
        if(map[property].hasOwnProperty(key) && key === term) {
          found.push(property);
        }
      }
    }
  }
  return found;
}

Upvotes: 2

Views: 79

Answers (5)

Kamil Kiełczewski
Kamil Kiełczewski

Reputation: 92467

Shortest

let newArray = myArray.map( x=>Object.keys(x)[0] ).filter( (k,i)=>myArray[i][k] ); 

In above solution first we use: map which works as for-loop to get array of keys (using Object.keys) ["item1", "item2", "item3", "item4"]. Then we filter that array by choose only those keys for which original array object has true. e.g myArray[0]["item1"] -> true (we use fact that filter funtion takes array element (k) and its index (i) which is the same for elements in myArray). In map and filter we use arrow functions.

Upvotes: 1

V. Sambor
V. Sambor

Reputation: 13389

Something much optimized than the accepted answer would look like this:

const arr = [
  { item1: true },
  { item2: false },
  { item3: true },
  { item4: false }
]

const result = [];
const len = arr.length;

for (let i = 0; i < len; ++i) {
  const obj = arr[i];
  const key = Object.keys(obj)[0];

  if(obj[key]) {
    result.push(key);
  }
}

console.log(result);

There is only one loop over the array, instead of map and filter which ends up looping twice.

Upvotes: 1

junvar
junvar

Reputation: 11584

Assuming myArray always contains objects with only 1 property.

let newArray = myArray
    .map(item => Object.entries(item)[0])
    .filter(([key, value]) => value)
    .map(([key, value]) => key)

Upvotes: 2

Ele
Ele

Reputation: 33726

Use the function reduce to build the desired output. The handler of the function reduce will get the keys and check for each value === true.

This approach checks for the whole set of keys within an object. Further, this way you only use one loop.

let myArray = [{item1: true},{item2: false},{item3: true},{item4: false}],
    result = myArray.reduce((a, c) => a.concat(Object.keys(c).filter(k => c[k] === true)), []);
    
console.log(result);

Upvotes: 1

Dacre Denny
Dacre Denny

Reputation: 30370

You could access the first key of each array item via Object.keys(), and use this to filter items with a true value for that first key, and then complete the process with a call to map() to transform the item to a value based on the same "first key" technique:

let myArray = [
  {item1: true},
  {item2: false},
  {item3: true},
  {item4: false}
]

let result = myArray
.filter(item => item[ Object.keys(item)[0] ] === true)
.map(item => Object.keys(item)[0])

console.log(result)

Upvotes: 1

Related Questions