区分同名的JSON元素

时间:2015-11-19 08:30:29

标签: javascript json

我有这个JSON文件

{
"items":[
    {
        "item1":1,
        "description":"descr",  
        "value":0,
    },
    {
        "item2":2,
        "description":"descr",
        "value":1,
    }
],
"shelfName":"top",
"shelfDescription":"The big one"
},
{
"items":[
    {
        "item1":2,
        "description":"descr",  
        "value":0,
    },
    {
        "item2":3,
        "description":"descr",
        "value":1,
    }
],
"shelfName":"bottom",
"shelfDescription":"The little one"
},

正如您可以清楚地看到的那样,它的结构是唯一不同的元素(shelfNameshelfDescription)与items处于同一级别,我需要选择,让我们说'一个item1货架的top元素。如果不重新构建JSON文件,怎么会这样做呢?

5 个答案:

答案 0 :(得分:1)

您可以使用lodash' _.findWhere。 Lodash图书馆在这里:https://lodash.com/

var rawData = [
  { 
    items: [1, 2, 3],
    shelfName: 'top'
  }, { 
    items: [4, 5, 6],
    shelfName: 'bottom'
  }
];
var foundIt = _.findWhere(rawData, {shelfName: 'bottom'});

然后foundIt.items将为您提供底架的物品!

foundIt.items // Returns [4, 5, 6]

(这假设您只有一个shelfNamebottom的对象。如果您有多个,则可以改为使用_.where。)_.findWhere的文档:{ {3}}

答案 1 :(得分:1)

使用.filter()搜索顶级数组,然后访问.map()中的相关媒体资源。重复内部结构。对于您的示例,假设obj包含JSON:

obj
  .filter(shelf => shelf.shelfName === 'top')
  .map(shelf => shelf.items.filter(item => typeof item.item1 !== 'undefined'))

在ES5中:

obj
  .filter(function (shelf) {
    return shelf.shelfName === 'top'
  })
  .map(function (shelf) {
    return shelf.items.filter(function (item) {
      return typeof item.item1 !== 'undefined'
    })
  })

这将从您的示例中返回:

[
  {
    "item1":1,
    "description":"descr",  
    "value":0
  }
]

答案 2 :(得分:0)

DEMO

obj.forEach(function (value) {
    if(value.shelfName === 'top'){
        value.items.forEach(function (value2) {
            if(value2.item1){
                console.log(value2.item1);
                return false;
            }
        });
        return false;
    }
});

您首先必须通过[]包围它来确保您的json有效。然后你可以遍历初始数组。对于每次迭代,您都会检查shelfName === 'top'。如果是,那么您循环浏览items,直到找到item1并返回

答案 3 :(得分:0)

根据您的需要,您可以通过在返回具有正确名称的对象的方法中迭代数组中的shelf-objects来解决此问题:

https://jsfiddle.net/kpnu7yfb/

var json = {"furniture":[{
"items":[
    {
        "item1":1,
        "description":"descr",  
        "value":0
    },
    {
        "item2":2,
        "description":"descr",
        "value":1
    }
],
"shelfName":"top",
"shelfDescription":"The big one"
},
{
"items":[
    {
        "item1":2,
        "description":"descr",  
        "value":0
    },
    {
        "item2":3,
        "description":"descr",
        "value":1
    }
],
"shelfName":"bottom",
"shelfDescription":"The little one"
}]};

function getShelf(shelfName){
    for(var i=0;i<json.furniture.length;i++){
     if(json.furniture[i].shelfName==shelfName) return json.furniture[i];
    }
}
var topshelf = getShelf("top");
alert("shelf named '" + topshelf.shelfName +"' (" + topshelf.shelfDescription+") has " + topshelf.items.length +" items"  );

答案 4 :(得分:0)

由于我看不到任何允许输入项目参数的功能,我使用while添加了我的循环版本。

如果函数找到该项,则返回包含项信息的对象。如果未找到任何内容,则返回“未找到”字符串。

功能

function getShelfData(shelfName,item){
 var l=o.length,s,sl; // o is your javascript object.
 while(l--){
  if((s=o[l]).shelfName==shelfName){ // o
   sl=(s=s.items).length;
   while(sl--){
    if(s[sl][item]){
     return s[sl]
    }
   }
  }
 }
 return "not found"
}

用法

getShelfData('bottom','item2');

<强>演示

http://jsfiddle.net/7ektcu0m/3/

<强>附加

我个人会避免任何类型的原生函数,例如forEachmapfilter,因为它们实际上比简单循环慢{{{ 1}} / while)您可以使用它来获得相同的结果。

虽然这适用于短列表,但如果您打算使用大数据集,我建议重新构建JSON字符串。

如果这个for似乎很难理解,它会在检查对象时缓存该对象。这样做可以提高整体性能并节省一些空间。

如果您确实阅读了代码,您还会注意到我重用了一些变量。性能再次提高,节省了一些字节。

如果您有任何问题,请询问

如果我错了,这是一个获取整个货架数据的示例

(s=o[l]).shelfName

然后可以应用非常相似的东西来获取项目

function getShelfData(shelfName){
 var l=o.length;
 while(l--)if(o[l].shelfName==shelfName)return o[l];
 return "not found"
}