Several issues:
forEachalways returnsundefined. You need to usemapinstead.(key, value["Penetration_2018"])is not a tuple, but a comma operator expression and results in the value ofvalue["Penetration_2018"]. Use square bracket notation instead.- A
Maphas no useful representation when cast to string. You need to turn it to an array or something else to get a more useful string representation:
Code:
const mapTest = new Map(
Object.entries(filterCounties).map(
([key, value]) => [key, value["Penetration_2018"]]
)
);
console.log(`This is mapTest ${JSON.stringify([...mapTest])}`);
With arrays it is more conventional to just apply map directly on the array, and it is a mystery why you would need a Map anyway. If you want the unique values, then use a Set:
const uniques = [...new Set(filterCounties.map(value => value["Penetration_2018"]))];
console.log(`This is uniques: ${uniques}`);
Answer from trincot on Stack OverflowObject.entries with forEach to map array of objects returns ...
node.js - Is it a bug on javascript Object entries foreach? - Stack Overflow
I m confused with Object.entries()[i]
For...in vs Object.keys
Videos
Several issues:
forEachalways returnsundefined. You need to usemapinstead.(key, value["Penetration_2018"])is not a tuple, but a comma operator expression and results in the value ofvalue["Penetration_2018"]. Use square bracket notation instead.- A
Maphas no useful representation when cast to string. You need to turn it to an array or something else to get a more useful string representation:
Code:
const mapTest = new Map(
Object.entries(filterCounties).map(
([key, value]) => [key, value["Penetration_2018"]]
)
);
console.log(`This is mapTest ${JSON.stringify([...mapTest])}`);
With arrays it is more conventional to just apply map directly on the array, and it is a mystery why you would need a Map anyway. If you want the unique values, then use a Set:
const uniques = [...new Set(filterCounties.map(value => value["Penetration_2018"]))];
console.log(`This is uniques: ${uniques}`);
Object.entries is pretty useless on an array. If necessary, you'd use the array entries method.
I thought that when using an arrow function, return was implicit?
An arrow function with a concise body implicitly returns the expression value, yes. However, in your first example, console.log does not return anything, and in both examples, forEach returns nothing. And in your second example, you use the comma operator for some kind of "tuple" notation while the Map constructor requires arrays.
Instead of trying to use "forEach to map array of objects", you should use the map method to map an array of objects!
const mapTest = new Map(filterCounties.map((value, key) => [key, value.Penetration_2018]));
console.log('This is mapTest:', mapTest);
As stated in the comments, objects are not required to iterate properties in insertion order. If you require the iteration order to match the insertion order, use a Map instead:
const map1 = new Map([
['01', "val1"],
["06", "val6"],
["13", "val13"],
["88", "val88"],
["100", "val100"]
]);
for (const [k, v] of map1) {
console.log(k + "-" + v);
}
An JavaScript Object is an unsorted key-value store, a.k.a. an Associative Array. This is comparable to Java's Maps or Python's dicts. There is absolutely no guarantees of any order when fetching or iterating over the keys, values or key-value pairs. Any order you may see is due to the internal implementation and can not be relied on. You may not even rely on it being deterministic.
These objects are equivalent:
const obj1 = {
'01': "val1",
"06": "val6",
"13": "val13",
"88": "val88",
"100": "val100"
}
const obj2 = {
"100": "val100",
"06": "val6",
"13": "val13",
"88": "val88",
'01': "val1"
}
For sorted entries, use Map or or Array.
The Docs say that Object.entries returns an array of given objects enumerable property [key,value] pairs . So yes its confusing if you look at this statement
const object3 = { 100: 'a', 2: 'b', 7: 'c' };
and end up getting ["2", "b"] when you call Object.entries(object3)[0].
When you are doing this Object.entries(object3)[0] , you are accessing a pair at the index of 0 returned by this function Object.entries(object) . The order of this array has nothing to do with how you defined the object3 in the first place. The order according to the doc is the same as the provided by a
for...in loop. I ran the for...in loop on the object and this is what i got as the order.
2,7,100.
This is why you are getting ["2", "b"] instead of ["100", "a"]. As others have mentioned here , the order seems to be that way because 2<7<100.
This is because the object has numeric keys and when you manipulate the object with the numeric keys the javascript sort the key-values in ascending order of the key value and since you have keys 2, 7, and 100. So, check this when you console.log the object Object.entries(object3) you get that sorted and when you access [0] you get Array ["2", "b"]
const object3 = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(object3));
Further clarification on sorting the object by ascending values of key when they are numeric. The javascript sorts them behind the scenes.
var a = {
10: 'ten',
5: 'five',
11: 'eleven',
1: 'one'
};
console.log(a);
Hey all, this is solely for for my own curiosity, but what would be preferred in any given situation while iterating over an object, "for...in", or "Object.keys(obj).forEach()"?
I generally favor "for...in", but it occurred to me the .forEach() method may work just as well.
Example:
var obj = { prop1 : "some val", prop2 : "some other val"};
for(key in obj){
console.log("Key: ", key)
console.log("Value: ", obj[key])
}
Object.keys(obj).forEach((key)=>{
console.log("For Each Key: ", key)
console.log("For Each Value: ", obj[key)
})
You can use the for-in loop as shown by others. However, you also have to make sure that the key you get is an actual property of an object, and doesn't come from the prototype.
Here is the snippet:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (var key in p) {
if (p.hasOwnProperty(key)) {
console.log(key + " -> " + p[key]);
}
}
For-of with Object.keys() alternative:
var p = {
0: "value1",
"b": "value2",
key: "value3"
};
for (var key of Object.keys(p)) {
console.log(key + " -> " + p[key])
}
Notice the use of for-of instead of for-in, if not used it will return undefined on named properties, and Object.keys() ensures the use of only the object's own properties without the whole prototype-chain properties
Using the new Object.entries() method:
Note: This method is not supported natively by Internet Explorer. You may consider using a Polyfill for older browsers.
const p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (const [key, value] of Object.entries(p)) {
console.log(`${key}: ${value}`);
}
Under ECMAScript 5, you can combine Object.keys() and Array.prototype.forEach():
var obj = { first: "John", last: "Doe" };
Object.keys(obj).forEach(function(key) {
console.log(key, obj[key]);
});
ECMAScript 6 adds for...of:
for (const key of Object.keys(obj)) {
console.log(key, obj[key]);
}
ECMAScript 8 adds Object.entries() which avoids having to look up each value in the original object:
Object.entries(obj).forEach(
([key, value]) => console.log(key, value)
);
You can combine for...of, destructuring, and Object.entries:
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
Both Object.keys() and Object.entries() iterate properties in the same order as a for...in loop but ignore the prototype chain. Only the object's own enumerable properties are iterated.