0

I've got object of objects:

let obj = {
  a: {
    af: {
      key: "k", val: "v"
    },
    bf: {
      key: "g", val: "h"
    }
  },
  b: {
    af: {
      key: "f", val: "w"
    },
    nf: {
      key: "u", val: "t"
    }
  }
};`

I'm trying to get an array of all values associated with key - in this case: ["k","g","f","u"] I tried to use Object.entries() in the for loop but I guess I do not understand how it works. I did simply as in docs:

for ([k,v] in Object.entries(obj)){
  console.log(k,v)
}

but my result is

0 undefined

1 undefined

which I completly do not understand. Could you please help me with explaining how this short code works?

let obj = {a: {af: {key: "k", val: "v"}, bf: {key: "g", val: "h"}}, b: {af: {key: "f", val: "w"}, nf: {key: "u", val: "t"}}};

for ([k,v] in Object.entries(obj)){
  console.log(k,v)
}
Malvinka
  • 1,185
  • 1
  • 15
  • 36
  • 2
    It might make more sense if you write `for .. of` not `for .. in`. Also bear in mind that you want properties that are 3 levels deep, and your call to Object.entries is only digging out the props one level deep – Caius Jard Dec 13 '20 at 17:48
  • 1
    `for (let [k,v] of Object.entries(obj)) {` – Mister Jojo Dec 13 '20 at 17:49
  • https://stackoverflow.com/questions/29285897/what-is-the-difference-between-for-in-and-for-of-statements-in-jav https://stackoverflow.com/questions/500504/why-is-using-for-in-for-array-iteration-a-bad-idea – Bergi Dec 13 '20 at 17:51

2 Answers2

1

Object.entries(obj) returns an array. Each item in the array represents one property of the object expressed as an array containing the property name and the property value.

x in someObject gets the iterable property names of the object.

The property names in an array are the numerical indexes.

Hence your output:

const [x,y] = "0";
console.log({x,y});

If you want to loop over the property values instead of the property names you need of (which loops over the values) not in.

let obj = {a: {af: {key: "k", val: "v"}, bf: {key: "g", val: "h"}}, b: {af: {key: "f", val: "w"}, nf: {key: "u", val: "t"}}};

for ([k,v] of Object.entries(obj)){
  console.log(k,v)
}

However, looping over an array should probably be done using forEach (or a traditional three-part for loop) instead, as it won't trip over unexpected enumerable properties that might be added to your array.

let obj = {a: {af: {key: "k", val: "v"}, bf: {key: "g", val: "h"}}, b: {af: {key: "f", val: "w"}, nf: {key: "u", val: "t"}}};

Object.entries(obj).forEach( ([k,v]) => console.log({k,v}) );
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Looping over an array should be done with `for … of` (which the OP tried but misspelled). Why do you recommend `forEach`? – Bergi Dec 13 '20 at 17:54
  • To be honest I had no idea that there is both `for...in` and `for...of` loops. Absolutely fantastic lesson, thank you both! – Malvinka Dec 13 '20 at 17:55
-1

for-in loops over the keys of an object, it doesn't include the values. Object.entries() returns an iterator, not an object.

Use forEach() to iterate over its results:

let obj = {a: {af: {key: "k", val: "v"}, bf: {key: "g", val: "h"}}, b: {af: {key: "f", val: "w"}, nf: {key: "u", val: "t"}}};

Object.entries(obj).forEach(([k, v]) => console.log(k, v));
Barmar
  • 741,623
  • 53
  • 500
  • 612