Reputation: 7694
I'm new to JavaScript and I'm really lost here. Here is some data produced by PHP json_encode()
(and limited to most pertinent keys) :
[
{
"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":""
}
]
I need to access price
and price_prefix
values (in JavaScript) knowing product_option_id
and product_option_value_id
.
How do I do that ? Should I go for a loop ?
Thanks for replies. Unless I missed something, it appears that in my case arrays (as ugly as they may be…) are much more efficient than all the proposed solutions (I'll try another approach, formatting a JSON object corresponding to my needs with PHP rather than using the "default" one, but it's off topic here). Though I'm not fond of adding libraries and it's a bit slower than most other solutions, I'll accept Matt's solution because it really seems to make life easier as far as JSON access is concerned. But it should be noted that Yeldard and Barmar's (almost cloned) solutions are faster than other propositions.
Upvotes: 2
Views: 1042
Reputation: 780724
Use nested loops to search through the main array and the sub-arrays, looking for the matching element.
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 }
}
}
}
}
}
Upvotes: 2
Reputation: 63524
Use filter
on the main array to grab the right object, filter again on the option_value_id, then map
on the returned array to get a single price/prefix object. map
and filter
both return arrays which is why you see the code picking up the first element ([0]
) in a couple of places.
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: "+" }
Upvotes: 2
Reputation: 74630
lodash would make this easier and neater. It provides _.find
or _.filter
depending on if your id's are unique or not.
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 )
For more complex data selection, you might want to look at sift.js. It's based on mongodb's query system.
var records = sift({
"product_option_id": "229",
"product_option_value": {
$elemMatch: {
"product_option_value_id": "22"
}
}
},
data_structure
)
Upvotes: 2
Reputation: 2068
Following would do:
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] || [];
}
Usage:
getProductValues(data, 229, 51)
Result:
{product_option_value_id: "21", option_value_id: "51", price: "1,22 €", price_prefix: "+"}
Upvotes: 2
Reputation: 20254
This should do it:
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];
}
If a matching item exists it will be assigned to matchingInner
Upvotes: 2
Reputation: 34189
Yes, you need to enumerate through the array and find your items:
Here is the working code which outputs price_prefix
and price
of product with product_option_id
= 228 and product_option_value_id
= 19. You can replace these values with your own.
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);
}
}
}
}
Upvotes: 1
Reputation: 3580
you can do like this
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;
}
}
Upvotes: 2