繁体   English   中英

通过KeyName查找JSON数组对象值

[英]Finding JSON Array Object Values by KeyName

我正在针对以下情况在JSON中寻找一种HashMap的实现形式。

我有以下结构的JSON:

{
"level1": {
    "level2": [{
        "product1": [
            "item1",
            "item2"
        ]
    }, {
        "product2": [
            "item1",
            "item2"
        ]
    }, {
        "product3": [
            "item5",
            "item6"
        ]
    }]
}
}

对于我的用例,我得到一个值,例如“ product3”,我想找到该键的值,即“ item5”,“ item6”。 我有一种方法,可以遍历整个level2对象,但想知道是否可以简单地使用key来查找值。

您可以自己构建一个对象或(在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]); 

我们使用Object.create(null)创建对象( map ),以便它没有原型,因此也没有像toStringvalueOf这样的预先存在的继承属性。

必须使用Object.keys结果上的内部循环,因为level2数组中的每个对象为其唯一属性都具有不同的名称。 这是一个不寻常且有点尴尬的结构。

在带有Map ES2015(又称“ ES6”)中,非常相似,只是使用new Mapset

var map = new Map();
data.level1.level2.forEach(function(entry) {
    Object.keys(entry).forEach(function(key) {
        map.set(key, entry);
    });
});

现场示例:

 var data = { "level1": { "level2": [{ "product1": [ "item1", "item2" ] }, { "product2": [ "item1", "item2" ] }, { "product3": [ "item5", "item6" ] }] } }; var map = new Map(); data.level1.level2.forEach(function(entry) { Object.keys(entry).forEach(function(key) { map.set(key, entry); }); }); var name = "product2"; console.log(map.get(name)); 

使用Array.someArray.indexOfObject.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]) -如果回调函数返回任何数组元素的真实值,则此函数返回true;否则,此函数返回true 在我的示例中, values变成thisArg参数,其中应包含所需的“ keyName”的值。
它将迭代所有“产品”对象,但是如果在当前对象的属性( Object.keys(v).indexOf(key) !== -1 )中找到所需的keyName ,它将立即立即停止循环。
作为并发条件,它应保存找到的对象的值,这可以通过真实的赋值表达式&& (values = v[key])
就这样。

您可以将数据转换为不同的结构。

 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); }, {}); } 

试试(假设level1level2是通用的)

 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); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM