按KeyName查找JSON数组对象值

时间:2016-05-26 06:31:42

标签: javascript json

我正在寻找Javascript for JSON中的HashMap实现,用于以下情况。

我有以下结构的JSON:

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

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

4 个答案:

答案 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")中,您只需使用Mapnew 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.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]) - 如果回调函数为任何数组元素返回 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)

尝试(假设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);