'Object.values vs Array.from, what's the difference?
I recently faced issues where I couldn't use .map on iterable objects and had to convert them to arrays with either Object.values or Array.from
I seem to get same result in both cases, so I'm wondering what the difference is. In which case do you use one over the other?
Solution 1:[1]
It's not true in the general case that you'll get the same result from Array.from(x) and Object.values(x) when x is an iterable object. In fact, it's fairly rare (just arrays and array-likes¹ that hide their length property by making it non-enumerable or inheriting it and don't have any other own, enumerable properties). Array.from will loop through the iterable object using iteration; Object.values will loop through the object looking for own, enumerable properties. For an array that doesn't have any non-array properties, that ends up being the same thing, but it's not true in the general case.
In the general case, Array.from and Object.values do very different things and have different results:
Array.fromcreates an array from any iterable or array-like object (an object with alengthand index properties like 0 and 1).Object.valuescreates an array of the values of an object's own enumerable properties. The object doesn't have to be iterable (Object.valuesdoesn't even look to see if it is.)Array.fromaccepts a second argument, a function that can be used to map the values from the iterable/array-like into new values for the array.
Here's an example where Object.values gets [] (because the Set has no own enumerable properties) but Array.from gets [1, 2, 3] (because the Set's iterator provides those three values):
const x = new Set([1, 2, 3]);
// Shows an empty array
console.dir(Object.values(x));
// Shows [1, 2, 3]
console.dir(Array.from(x));
Conversely, here's one where Object.values returns [1, 2, 3] because the object has those as own enumerable properties, but Array.from returns [] because the object is neither iterable nor array-like:
const x = {a: 1, b: 2, c: 3};
// Shows [1, 2, 3];
console.dir(Object.values(x));
// Shows []
console.dir(Array.from(x));
¹ An array-like object is an object with:
- A
lengthproperty - Properties named with strings that are numbers in the normal decimal form for the values
0throughlength - 1(but there can be gaps).
For instance, this is an array-like object:
const obj = {0: "zero", 1: "one", length: 2};
(I've used number literals for the property names, but they'll be converted to string.)
Note that that object will give you different results for Array.from and Object.values because length is an own, inherited property.
Solution 2:[2]
Array.from creates a new array, usually from another array, but can also be used on Set. It also has a second arguments, that allows to map each element to another value.
Object.values on the other hand creates a new array with the values from the supplied object.
I'm not exactly sure why you say they do the same thing, as they don't. Except maybe the fac that you end up with an array as the results. Take this example for instance:
Object.values({a: 2, b:3}) // will return [2, 3]
on the other hand
Array.from({a: 2, b:3}) // will return [], as an object is not an array-like object
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Radu Diță |
