按嵌套JSON数组

时间:2015-08-12 09:40:22

标签: javascript json key-value

我是JavaScript的新手,我真的迷失在这里。以下是PHP json_encode()生成的一些数据(仅限于最相关的密钥):

[
  {
    "product_option_id":"229",
    "product_option_value":
    [
      {
        "product_option_value_id":"21",
        "option_value_id":"51",
        "price":"1,22 €",
        "price_prefix":"+"
      },
      {
        "product_option_value_id":"22",
        "option_value_id":"52",
        "price":false,
        "price_prefix":"+"
      },
      {
        "product_option_value_id":"23",
        "option_value_id":"53",
        "price":"2,42 €",
        "price_prefix":"+"
      }
    ],
    "option_id":"14",
    "type":"radio",
    "value":""
  },
  {
    "product_option_id":"228",
    "product_option_value":
    [
      {
        "product_option_value_id":"19",
        "option_value_id":"49",
        "price":"1,22 €",
        "price_prefix":"+"
      },
      {
        "product_option_value_id":"20",
        "option_value_id":"50",
        "price":"2,42 €",
        "price_prefix":"+"
      }
    ],
    "option_id":"13",
    "type":"select",
    "value":""
  }
]

我需要访问知道priceprice_prefix的{​​{1}}和product_option_id值(在JavaScript中)。

我该怎么做?我应该去玩一个循环吗?

更新

感谢您的回复。除非我遗漏了某些内容,否则in my case数组(尽管它们可能很丑陋)似乎比所有提议的解决方案都要much more efficient(我会尝试另一种方法,格式化符合我需求的JSON对象使用PHP而不是使用“默认”,但这不是主题。虽然我不喜欢添加库并且它比大多数其他解决方案慢一点,但我会接受Matt的解决方案,因为就JSON访问而言,它似乎真的让生活变得更轻松。但值得注意的是,Yeldard和Barmar(几乎克隆的)解决方案比其他命题更快。

7 个答案:

答案 0 :(得分:2)

你可以这样做

    for(var i in jsonData) {
    var item = jsonData[i];
    if(item.product_option_id == 229) {
        for(var j in item.product_option_value){
            var item1 = item.product_option_value[j];
            if(item1.product_option_value_id == 21) {
                //your item here
                break;
            }
        }
       break;
    }

}

答案 1 :(得分:2)

这应该这样做:

var productOptionId = 229;
var productOptionValue = 22;

var matchingOuter = yourData.filter(function(i){
    return i.product_option_id === productOptionId; 
})[0];

if (matchingOuter) {
    var matchingInner = matchingOuter.product_option_value.filter(function(i){
        return i.product_option_value === productOptionValue;
    })[0];
}  

如果存在匹配项,则会将其分配给matchingInner

答案 2 :(得分:2)

使用嵌套循环搜索主数组和子数组,寻找匹配元素。

function find_product(product_option_id, product_option_value_id) {
    for (var i = 0; i < products.length; i++) {
        var product = products[i];
        if (product.product_option_id == product_option_id) {
            for (var j = 0; j < product.product_option_value.length; j++) {
                var value = product.product_option_value[j];
                if (value.product_option_value_id == product_option_value_id) {
                    return { price: value.price, price_prefix: value.price_prefix }
                }
            }
        }
    }
}

答案 3 :(得分:2)

在主阵列上使用filter来获取正确的对象,再次在o​​ption_value_id上​​过滤,然后在返回的阵列上map获取单个价格/前缀对象。 mapfilter都会返回数组,这就是为什么你会看到代码在几个地方获取第一个元素([0])的原因。

function getData(data, options) {
    return data.filter(function (product) {
      return product.product_option_id === options.id;
    })[0].product_option_value.filter(function (details) {
       return details.product_option_value_id === options.optionId;
    }).map(function(el) {
      return { price: el.price, prefix: el.price_prefix }
    })[0];
}

getData(data, { id: '229', optionId: '23' }); // { price: "2,42 €", prefix: "+" }

DEMO

答案 4 :(得分:2)

以下会这样做:

function getProductValues(products, product_option_id, product_option_value_id) {
    if (!product_option_id || !product_option_value_id) {
        return;
    }

    return products.filter(function(product) {
        return +product.product_option_id === product_option_id;
    }).map(function (product) {
        var option_values = product.product_option_value;
        return option_values.filter(function (option) {
            return +option.option_value_id === product_option_value_id;
        })[0] || [];
    })[0] || [];
}

用法:

getProductValues(data, 229, 51)

结果:

{product_option_value_id: "21", option_value_id: "51", price: "1,22 €", price_prefix: "+"}

答案 5 :(得分:2)

lodash会让这更容易和更整洁。它提供_.find_.filter,具体取决于您的ID是否唯一。

var record = _.find( data_structure, {
  "product_option_id": "229"
})
if ( !record ) throw new Error("Record not found");

var value = _.find( record.product_option_value, {
  "product_option_value_id":"22" 
})
if ( !value ) throw new Error("Value not found");

console.log( "price[%s] prefix[%s]", value.price, value.price_prefix )

Demo

对于更复杂的数据选择,您可能需要查看sift.js。它基于mongodb's query system

var records = sift({ 
    "product_option_id": "229", 
    "product_option_value": {
      $elemMatch: {
        "product_option_value_id": "22"  
      }
    }
  },
  data_structure
)

答案 6 :(得分:1)

是的,您需要枚举数组并找到您的项目:

以下是输出price_prefixprice产品product_option_id = 228且product_option_value_id = 19的工作代码。您可以用自己的值替换这些值。< / p>

for (var i = 0; i < obj.length; i++) // Enumerate through array
{
    var item = obj[i];
    if (item.product_option_id === "228") // Filtering items by product_option_id
    {
        // When necessary product_option_id found
        for (var j = 0; j < item.product_option_value.length; j++) // Enumerate through its products
        {
            var productItem = item.product_option_value[j]; 
            if (productItem.product_option_value_id === "19") // Filtering by product_option_value_id
            {
                // here it is. productItem is found! do whatever you want with it
                alert(productItem.price_prefix + " " + productItem.price);
            }
        }
    }
}

Working JSFiddle demo