I have an object in the below format and I need to get all values from the Price
property at all levels of the object.
var o = {
Id: 1,
Price: 10,
Attribute: {
Id: 1,
Price: 2,
Modifier: {
Id: 34,
Price: 33
}
}
};
I was thinking of LinqToJS and jquery.map()
methods but I'd like to get a method as generic as possible. I tried this but it only works at the first level:
var keys = $.map(o, function(value, key) {
if (key == "Price") {
return value;
}
});
You can use a recursive function which tests the type of name of the property and its type. If it's name is Price
, add it to an array. If it's an object, recurse through that object to find a Price
key. Try this:
function getPrices(obj, arr) {
$.each(obj, function(k, v) {
if (k == "Price")
arr.push(v);
else if (typeof(v) == 'object')
getPrices(obj[k], arr);
});
return arr;
}
var prices = getPrices(o, []);
console.log(prices); // = [10, 2, 33]
Working example
You can use jQuery's $.map()
to do this very easily:
var o = {
Id: 1,
Price: 10,
Attribute: {
Id: 1,
Price: 2,
Modifier: {
Id: 34,
Price: 33
}
}
};
var res = $.map(o, function mapper(obj, key) {
return key === "Price" ? obj : $.map(obj, mapper)
});
document.querySelector("pre").textContent = JSON.stringify(res)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<pre></pre>
This works because of the odd feature jQuery's $.map
has where if you return an Array from the callback, it gets flattened into the result.
Therefore we can recursively call $.map
with the same function on anything that's not the Price
key, and the array it returns will just get emptied into the final result.
You can avoid some calls if you check typeof obj === "object"
if you wish.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With