简体   繁体   中英

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;
}

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)

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)

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

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 . eg 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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM