最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Creating an array from object properties with Object.keys() vs Object.values() - Stack Overflow

programmeradmin2浏览0评论

Here's an object of cat breeds, and the number of cats in each:

const cats = {
  abyssinian: {
    number: 23
  },
  persian: {
    number: 12
  },
  siamese: {
    number: 7
  }
};

Suppose I wanted to calculate the total sum of cats. I'll use reduce to calculate the sum of array values.

But to create an array from the object above, I have two options:

  1. Object.keys()
  2. Object.values()

// object
const cats = { abyssinian: { number: 23 }, persian: { number: 12 }, siamese: { number: 7 } };

// sum array values with reduce
const total = numbers => numbers.reduce((acc, cur) => acc + cur);

// 1.
// create array with Object.keys()
const numbersByKeys = Object.keys(cats).map(breed => cats[breed].number);
console.log(`Sum with Object.keys(): ${total(numbersByKeys)}`);

// 2.
// create array with Object.values()
const numbersByValues = Object.values(cats).map(breed => breed.number);
console.log(`Sum with Object.values(): ${total(numbersByValues)}`);

Here's an object of cat breeds, and the number of cats in each:

const cats = {
  abyssinian: {
    number: 23
  },
  persian: {
    number: 12
  },
  siamese: {
    number: 7
  }
};

Suppose I wanted to calculate the total sum of cats. I'll use reduce to calculate the sum of array values.

But to create an array from the object above, I have two options:

  1. Object.keys()
  2. Object.values()

// object
const cats = { abyssinian: { number: 23 }, persian: { number: 12 }, siamese: { number: 7 } };

// sum array values with reduce
const total = numbers => numbers.reduce((acc, cur) => acc + cur);

// 1.
// create array with Object.keys()
const numbersByKeys = Object.keys(cats).map(breed => cats[breed].number);
console.log(`Sum with Object.keys(): ${total(numbersByKeys)}`);

// 2.
// create array with Object.values()
const numbersByValues = Object.values(cats).map(breed => breed.number);
console.log(`Sum with Object.values(): ${total(numbersByValues)}`);

When would I choose one over the other? What are the best practices here?

Share Improve this question edited Mar 7, 2019 at 8:01 Jack Bashford 44.1k11 gold badges55 silver badges82 bronze badges asked Mar 3, 2019 at 23:46 Robin MétralRobin Métral 3,2093 gold badges19 silver badges35 bronze badges 3
  • There is also Object.enteries where you get [key, value] – chriss Commented Mar 3, 2019 at 23:50
  • Did you end up doing your own profiling? – Brian Drake Commented Feb 2, 2022 at 13:24
  • Wow this is old :P Back then jsperf was up, and another comment mentioned that .keys tended to be faster. But I remember noticing that it also depended on the browser (but that seems strange? I don't know TBH), so I'd just honestly pick what feels more natural. In my example I don't need the keys at all (just the number of cats in each) so I'd pick .values – Robin Métral Commented Feb 2, 2022 at 16:33
Add a comment  | 

7 Answers 7

Reset to default 10

Use .keys() if you need to do something with the keys other than to retrieve the values. Otherwise, you're only getting the keys in order to access the values, which is redundant if you can get the values directly using a different method - so, in that case, might as well use Object.values() from the beginning.

An example of where Object.keys could be useful:

const obj = {
  prop1: 'val1',
  prop2: 'val2'
};

const result = Object.keys(obj).map((key) => [key, obj[key]]);
console.log(result);

You may also use Object.entries to get both the key and value at once:

const obj = {
  prop1: 'val1',
  prop2: 'val2'
};

const result = Object.entries(obj).map(([key, val]) => key + '---' + val);
console.log(result);

Array.from(arrayLike [, mapFn [, thisArg]]) is also another method to create an array from an array-like or iterable object and is really simple. Second argument is a map function to call on every element of the array

 const cats = {
    abyssinian: {
      number: 23
    },
    persian: {
      number: 12
    },
    siamese: {
      number: 7
    }
};
const catsArray = Array.from(Object.values(cats), breed => breed.number)
console.log(catsArray);

Since you're not actually using the keys, you can use reduce with Object.values and destructuring to make it simpler and more concise:

const cats = {
  abyssinian: {
    number: 23
  },
  persian: {
    number: 12
  },
  siamese: {
    number: 7
  }
};

const totalCats = Object.values(cats).reduce((acc, { number }) => acc + number, 0);

console.log(totalCats);

If performance is a factor, you may want to stick with Object.keys

Here is another person's comparison on the performance of the different ways to iterate over an object.

“5 Techniques to Iterate Over JavaScript Object Entries and their Performance”

const object1 = { "11-15" : 115, "16-20" : 68, "21-25" : 4, "26-30" : 0 };

const result = Object.keys(object1).map((key) => {return {name:key, population:object1[key]}});

//[{ name: "11-15", population: 115 }, { name: "16-20", population: 68 }, { name: "21-25", population: 4 }, { name: "26-30", population: 0 }]

console.log(result);

var total = Object
  .entries(cats)
  .reduce((acc, [name, {number}])=> acc + number , 0);
console.log(total); // 42
const iterableValues = function* (obj) { for (let i of Object.values(obj)) yield i;}
let result = 0;
for (let {number} of iterableValues(cats)) result += number;
发布评论

评论列表(0)

  1. 暂无评论