Javascript 嵌套JSON数组上的按值访问
我是JavaScript新手,在这里我真的迷路了。以下是PHPJavascript 嵌套JSON数组上的按值访问,javascript,json,key-value,Javascript,Json,Key Value,我是JavaScript新手,在这里我真的迷路了。以下是PHPjson_encode()生成的一些数据(仅限于最相关的键): 我需要访问price和price\u prefix值(在JavaScript中),知道product\u option\u id和product\u option\u id 我该怎么做?我应该去兜一圈吗 更新: 谢谢你的回复。除非我遗漏了什么,否则看起来数组(尽管它们可能很难看…)比所有建议的解决方案都要复杂(我将尝试另一种方法,用PHP格式化符合我需要的JSON对象,而
json_encode()
生成的一些数据(仅限于最相关的键):
我需要访问price
和price\u prefix
值(在JavaScript中),知道product\u option\u id
和product\u option\u id
我该怎么做?我应该去兜一圈吗
更新:
谢谢你的回复。除非我遗漏了什么,否则看起来数组(尽管它们可能很难看…)比所有建议的解决方案都要复杂(我将尝试另一种方法,用PHP格式化符合我需要的JSON对象,而不是使用“默认”对象,但这是离题的)。虽然我不喜欢添加库,而且它比大多数其他解决方案都慢一点,但我还是会接受Matt的解决方案,因为就JSON访问而言,它确实让生活变得更轻松。但需要注意的是,耶尔达德和巴尔马(几乎是克隆的)的解决方案比其他方案更快。你可以这样做
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;
}
}
这应该做到:
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];
}
如果存在匹配项,则它将被分配给
匹配器是,您需要通过数组枚举并找到您的项:
这是工作代码,它输出产品选项id
=228和产品选项值id
=19的产品的价格前缀
和价格
。您可以用自己的值替换这些值
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);
}
}
}
}
for(var i=0;i
.使用嵌套循环搜索主数组和子数组,查找匹配的元素
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 }
}
}
}
}
}
函数查找产品(产品选项id、产品选项值id){
对于(变量i=0;i
在主数组上使用以获取正确的对象,在选项\u value\u id上再次过滤,然后在返回的数组上获得单个价格/前缀对象map
和filter
都是返回数组,这就是为什么您会看到代码在几个地方拾取第一个元素([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: "+" }
以下方法可以:
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: "+"}
会使这更容易和整洁。它提供或取决于您的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 )
对于更复杂的数据选择,您可能需要查看。这是基于
你已经试过什么了?你试过循环吗?你必须使用嵌套循环。@Andy:事实上,问题是“什么是最有效的方法?”-我知道如何循环。在发表之前,我重新措辞,认为它可能与主题无关,并失去了意义,对不起。当然,我在发布之后才发现。我正在阅读,它确实有帮助(我考虑删除我的问题),但目前我没有看到任何关于按值访问的内容。出于兴趣,在性能测试中测试预处理数组值(ABC)的目的是什么?这就是您将在PHP中创建的格式吗?它报告所有的价格,而不仅仅是他正在寻找的价格。出于一系列原因,您不应该在数组的
循环中使用。IE 6已停止支持;别担心,所有人都在使用latest@raghavendra,不知道你说的IE6是什么意思,但是。@raghavendra不,我没有。OP没有提到价值观的唯一性。所以,如果值是唯一的,则不需要打断。若值不是唯一的,那个么你们怎么知道OP不想把它们全部输出呢?反正只有229或228个问题,我同意toolodash似乎真的让生活更轻松了。虽然您的解决方案可以在JSFIDLE上运行,但您知道为什么吗?(我得到“TypeError:t.call不是一个函数。”)您使用的是一个谓词需要一个函数(因此t.call
)。lodash支持下划线API,但对其进行了扩展,以支持我使用的对象表示法。根据我的经验,我发现lodash更好,尤其是在发布/测试区域。尝试寻找感谢-我可以发誓我找到了lodash.js,不明白它是如何变成下划线的…最好在if
测试中使用“==”而不是“=”
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 )
var records = sift({
"product_option_id": "229",
"product_option_value": {
$elemMatch: {
"product_option_value_id": "22"
}
}
},
data_structure
)