2

Instead of using object literal syntax to access nested values in objects, I'm trying to use es6 Map object, which has a convenient map.get() method. I'm trying to avoid having to do the following with normal Javascript objects.

// access deeply nested values...
obj['k1'] &&
obj['k1']['k2'] &&
obj['k1']['k2']['k3']

Am I building the map wrong? only map.get('k1') works (can't get nested map values, just the whole thing under k1: is given as a value).

var obj = {'k1': {'k2': {'k3': 'Test Value'}}};
const map = new Map(Object.entries(obj));

console.log(map.get('k1')); 
console.log(map.get('k2')); 
console.log(map.get('k3')); 

4
  • You're only mapping one key, k1, in the new map. A map by itself won't solve your problem; you still need to traverse the structure to drill down. Commented Jun 27, 2018 at 17:38
  • Your other keys are nested inside the value of k1, Object.entries(obj) will give only one key/value pair, so the resulting map will also only have that one. Commented Jun 27, 2018 at 17:38
  • You could always extend Map to implement a multi-level get so you could do something like .getml('k1.k2.k3') ... but internally it's going to have to access each level in turn similarly to what you're trying to avoid. A better question might be: If you're not using those top levels of your data structure, why do you have them? Commented Jun 27, 2018 at 17:42
  • You seem to be looking for easier syntax to access potentially non-existant nested properties, not for a Map. Commented Mar 22, 2019 at 19:04

4 Answers 4

3

Your question about querying a nested object using Map is invalid. Map cannot do this. You either have to flatten your object prior to putting it into Map or find an alternative way that supports querying nested data.

I would advise against flattening your structure for the sole purpose of using Map. How do you handle key collisions? It becomes more complex.

So let's look at some ways to query nested data:

// how to query a nested data structure.

const get = (prop, ...props) => obj =>
  obj == null || prop == null
    ? obj
    : get(...props)(obj[prop])

const obj = {'k1': {'k2': {'k3': 'Test Value'}}};
const result = get('k1', 'k2', 'k3')(obj) // => 'Test Value'

You can also use a library like Ramda.

import path from 'ramda/src/path

const obj = {'k1': {'k2': {'k3': 'Test Value'}}};
const result = path(['k1', 'k2', 'k3'], obj)  // => 'Test Value'
Sign up to request clarification or add additional context in comments.

Comments

2

You need to iterate all keys and the nested objects as well.

function add(object, map) {
    Object.entries(object).forEach(([k, v]) => {
        map.set(k, v);
        if (v && typeof v === 'object') {
            add(v, map);
        }
    });
}

var obj = { k1: { k2: { k3: 'Test Value' } } };
const map = new Map;

add(obj, map);

console.log(map.get('k1')); 
console.log(map.get('k2')); 
console.log(map.get('k3')); 

1 Comment

A very smart way of creating nested maps. Love it.
0

You can try es6 destructuring 101.

let obj = {'k1': {'k2': {'k3': 'Test Value'}}};

let {k1} = obj;
let {k1: {k2}} = obj;
let {k1: {k2: {k3}}} = obj;

console.log(k1);
console.log(k2);
console.log(k3)

I hope this will help.

Comments

0

I'm doing something like this to create graphs/trees right now. This isn't exactly what I'm doing but it should give you the idea.

In es5 I would say

let root = {
  1:  {
       a: 'hi from a'
       b: ...
       }  
  2:  {...}
}

root[1][a]; //returns 'hi from a'
root['getme']['abeer']; //Type Error 

using Map:

  let root = new Map();
  root.set(1, new Map());
  root.get(1).set('a', 'hi from a');

  root.get(1).get('a');  //returns 'hi from a'

  root.get(1).get('me a beer');  //undefined  

  root.get('me').get('a-beer'); 
  //Uncaught TypeError: Cannot read property 'get' of undefined

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.