Reputation: 285
I am working with an API right now and I am using details[5].Value
to target information in the following format:
details:
"value":[
{
"ID": "6",
"Name": "Links",
"Value": "URL"
},
{
"ID": "7",
"Name": "Other",
"Value": "URL"
}
etc
]
The problem is that the location inside of the JSON response is likely to change in the future, making my code obsolete and as the url has the potential to change as well, I cannot target that.
I want a way to target the value of url, mostly, because of this, by the value of the "Name"
property. However, if I use something like
_.where(details, { Name: "Links" }).Value
It comes back as undefined. I am not sure if there would be another way to get to the information?
Upvotes: 0
Views: 1324
Reputation: 434665
There are a couple points of confusion here.
_.where
returns an array:
Looks through each value in the list, returning an array of all the values that contain all of the key-value pairs listed in properties.
so your _.where(details, obj).Value
will (almost) always give you undefined
because an array is unlikely to have a Value
property. _.findWhere
on the other hand does return a single value:
Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.
Secondly, your details
appears to look like:
let details = {
value: [
{ ID: '6', Name: 'Links', Value: 'URL' },
{ ID: '7', Name: 'Other', Value: 'URL' },
...
]
}
so you don't want to search details
, you want to search details.value
.
Putting them together:
_(details.value).findWhere({ Name: 'Links' }).Value
or
_.findWhere(details.value, { Name: 'Links' }).Value
You could use Array.prototype.find
(or Array.prototype.filter
if you're looking for all matches) and write your own callback but you already have Underscore available so why bother? Furthermore, Backbone collections have findWhere
and where
methods and there are advantages to matching Backbone's overall terminology.
Upvotes: 2
Reputation: 33726
An alternative is using the Javascript built-in function find
to get a specific object within an array.
byThis
parameter is an object, the whole set of key-values
must match with the key-values
of every object within the target array.byThis
is a string every object will be treated as string to make the necessary comparison.let details = { "value": [{ "ID": "6", "Name": "Links", "Value": "URL" }, { "ID": "7", "Name": "Other", "Value": "URL" }]};
let findBy = (array, byThis) => {
return array.find(o => {
if (typeof byThis === 'object') return Object.keys(byThis).every(k => o[k] === byThis[k]);
else if (typeof byThis === 'string') return o.toString() === byThis;
});
}
let found = findBy(details.value, {Name: "Links"});
console.log(found);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 7923
Take a look at this mini function. Let me know if there is something wrong
This is the ES5 Version
function f(key, value, array){
return array.value.filter(function(sub_array){
return sub_array[key] == value;
});
}
This is the ES6 Golfed Version
f=(k,v,a)=>a.value.filter(_=>_[k]==v)
//This is your JSON
var details = {
value: [
{
"ID": "6",
"Name": "Links",
"Value": "URL"
},
{
"ID": "7",
"Name": "Other",
"Value": "URL"
}
]
}
// Short code
f=(k,v,a)=>a.value.filter(_=>_[k]==v)
// f is the function name
// Recives k = array key, v = value, a = array
// filter by the given key and value
// return the result as an array
console.log(f('Name', 'Links', details))
Upvotes: 0