我正在寻找Javascript for JSON中的HashMap实现,用于以下情况。
我有以下结构的JSON:
{
"level1": {
"level2": [{
"product1": [
"item1",
"item2"
]
}, {
"product2": [
"item1",
"item2"
]
}, {
"product3": [
"item5",
"item6"
]
}]
}
}
对于我的用例,我得到一个值,比如'product3',我想找到这个键的值,即“item5”,“item6”。我有办法,我可以遍历整个level2对象,但想知道我是否可以简单地使用键来查找值。
答案 0 :(得分:3)
您可以自己构建一个对象或(在ES2015中)Map
:
这是使用对象的ES5示例:
var map = Object.create(null);
data.level1.level2.forEach(function(entry) {
Object.keys(entry).forEach(function(key) {
map[key] = entry;
});
});
实例:
var data = {
"level1": {
"level2": [{
"product1": [
"item1",
"item2"
]
}, {
"product2": [
"item1",
"item2"
]
}, {
"product3": [
"item5",
"item6"
]
}]
}
};
var map = Object.create(null);
data.level1.level2.forEach(function(entry) {
Object.keys(entry).forEach(function(key) {
map[key] = entry;
});
});
var name = "product2";
console.log(map[name]);

我们使用map
创建对象(Object.create(null)
),因此它没有原型,因此没有预先存在的继承属性,如{{1 }和toString
。
valueOf
结果的内部循环是必要的,因为Object.keys
数组中的每个对象的唯一属性都有不同的名称。这是一个不寻常的,有点尴尬的结构。
在使用level2
的ES2015(又名" ES6")中,您只需使用Map
和new Map
非常相似:
set
实例:
var map = new Map();
data.level1.level2.forEach(function(entry) {
Object.keys(entry).forEach(function(key) {
map.set(key, entry);
});
});

答案 1 :(得分:1)
使用Array.some
,Array.indexOf
和Object.keys
函数的“单行”优化解决方案(无需遍历所有“产品”对象):
// json is your initial object
var key = 'product3', values;
json['level1']['level2'].some((v) => Object.keys(v).indexOf(key) !== -1 && (values = v[key]), values);
console.log(values); // ["item5", "item6"]
<强>解释强>:
arr.some(callback[, thisArg])
- 如果回调函数为任何数组元素返回 truthy 值,则此函数返回 true ;在我的示例中,values
变为thisArg
参数,该参数应包含所需“keyName”的值
它将遍历所有“产品”对象,但如果在当前对象(Object.keys(v).indexOf(key) !== -1
)的属性中找到所需的 keyName ,则会立即停止循环。
作为并发条件它应该保存找到的对象的值,这可以通过 truthy 赋值表达式&& (values = v[key])
来实现。
就是这样。
答案 2 :(得分:0)
您可以将数据转换为不同的结构。
const data = {
"level1": {
"level2": [{
"product1": [
"item1",
"item2"
]
}, {
"product2": [
"item3",
"item4"
]
}, {
"product3": [
"item5",
"item6"
]
}]
},
"level1b": {
"level2": [{
"product1": [
"item1b",
"item2"
]
}, {
"product2": [
"item3",
"item4"
]
}, {
"product3": [
"item5",
"item6"
]
}]
}
};
const transformed = Object
.keys(data)
.reduce((obj, key) => {
const value = data[key];
return Object.assign(obj, {[key]: transformLvl2(value)});
}, {});
console.log(transformed.level1.level2.product2);
console.log(transformed.level1.level2.product1);
console.log(transformed.level1.level2.product3);
console.log(transformed.level1b.level2.product1);
function transformLvl2(level2) {
return Object
.keys(level2)
.reduce((obj, key) => {
const value = level2[key];
return Object.assign(obj, {[key]: transformLvl3(value)});
}, {});
}
function transformLvl3(level3) {
return level3
.reduce((obj, value) => {
return Object.assign(obj, value);
}, {});
}
答案 3 :(得分:0)
尝试(假设level1
和level2
是通用的)
var obj = {
"level1": {
"level2": [{
"product1": [
"item1",
"item2"
]
}, {
"product2": [
"item1",
"item2"
]
}, {
"product3": [
"item5",
"item6"
]
}]
}
};
var keyName = "product3";
var items = [];
Object.keys(obj).forEach(function(key) {
Object.keys( obj[key] ).forEach(function(key1){
obj[key][key1].forEach(function(obj1){
Object.keys(obj1).forEach(function(key2) {
if (key2 == keyName) {
items = items.concat(obj1[key2]);
}
});
});
});
});
console.log(items);