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'));
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'));
Share
Improve this question
edited Jun 27, 2018 at 21:18
Brian Tompsett - 汤莱恩
5,89372 gold badges61 silver badges133 bronze badges
asked Jun 27, 2018 at 17:35
GallaxharGallaxhar
1,0361 gold badge16 silver badges30 bronze badges
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. – Mark 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. – ASDFGerte 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? – Tibrogargan 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
. – Bergi Commented Mar 22, 2019 at 19:04
4 Answers
Reset to default 3Your 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 bees more plex.
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'
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'));
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.
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