Reputation: 63815
I'm trying to parse some JSON that is sent to me and it's all in the format of
[{key:value},{key2:value2}, ... ]
What would be the best way to get the value of key2
in this? Is there a way to do it without doing a for loop?
Upvotes: 16
Views: 53662
Reputation: 875
Use .filter() method for this object array, for example in your case:
var objArray = [{key:"Hello"},{key2:"Welcome"} ];
var key2Value=objArray.filter(x=>x.key2)[0].key2;
Upvotes: 2
Reputation: 750
Javascript Array comes with methods that do just what you are asking for - find entries without you having to code a for-loop.
You provide them with the condition that you want. A compact and convenient way to do that is with an arrow (or "lambda") function. In your case, you are looking for array entries that have a specific key, so the arrow function could look something like this:
e => e.hasOwnProperty("key2")
Following the lead of some of the others, let's start with the assumption
var arr = [{key:"value"}, {key2:"value2"}, {key3:"value3"}]
If you expect that at most one member of the array has the key you want, you can use the find()
function. It will test each array member until it finds one where your condition is true, and return it. If none are true, you'll get undefined
.
var foundentry = arr.find(e => e.hasOwnProperty("key2"))
Either foundentry
will be undefined
or it will be the {key2:"value2"}
that you are looking for, and can extract value2
from it.
If arr
can have more than one entry with the key that you are looking for, then instead of find()
use filter()
. It gives back an array of entries that meet your criteria.
var foundarray = arr.filter(e => e.hasOwnProperty("key2"))
Upvotes: 9
Reputation: 90746
Not really, but it wouldn't be hard to create a function to do that. However, it would indeed involves a for
loop.
For the sake of completion, that would be the function:
function selectWhere(data, propertyName) {
for (var i = 0; i < data.length; i++) {
if (data[i][propertyName] !== null) return data[i][propertyName];
}
return null;
}
Usage:
var key2value = selectWhere(data, "key2");
Upvotes: 8
Reputation: 1318
Heyas. You can use the lodash library's .reduce() or .transform() functions to implement this. Lodash is more modular than underscore (Underscore around 5kb, Lodash around 17kb), but is generally lighter because you only include the specific modules you need (please see: https://news.ycombinator.com/item?id=9078590 for discussion). For this demonstration I will import the entire module (generally not an issue on the backend): I wrote these snippets for either scenario which handle both numeric and non-numeric arguments.
https://lodash.com/docs#reduce
https://lodash.com/docs#transform
Pull in lodash:
var _ = require('lodash');
_.reduce() to where clause:
var delim = ' WHERE ', where = _.isEmpty(options) ? '' : _.reduce(options, function(r, v, k) {
var w = r + delim + k + '=' + (_.isNumber(v) ? v : ("'" + v + "'"));
delim = ' AND ';
return w;
}, '');
_.transform() to where clause:
var where = _.isEmpty(options) ? '' : ' WHERE ', delim = '';
_.transform(options, function(r, v, k) {
where = where + delim + k + '=' + (_.isNumber(v) ? v : ("'" + v + "'"));
delim = ' AND ';
});
Hope that helps.
Upvotes: 0
Reputation: 1373
Top answer does the job. Here's a one liner version of it using lodash (same as underscore for the most part):
var result = _.filter(data, _.partialRight(_.has, 'key2'));
In lodash, select is just an alias for filter. I pass it the data array filled with objects. I use _.has
as the the filter function since it does exactly what we want: check if a property exists.
_.has
expects two args:
_.has(object, path)
Since _.has
expects two arguments, and I know one of them is always constant (the path argument). I use the _.partialRight
function to append the constant key2
. _.partialRight
returns a new function that expects one argument: the object to inspect. The new function checks if obj.key2
exists.
Upvotes: 0
Reputation: 1686
jQuery grep() is a good analog for a Where clause:
var array = [{key:1},{key:2}, {key:3}, {key:4}, {key:5}];
var filtered = jQuery.grep(array, function( item, index ) {
return ( item.key !== 4 && index > 1 );
});
Your filtered array will then contain two elements,
[{key:3}, {key:5}]
Upvotes: 3
Reputation: 42099
Here's an example that prototype's the Array object. Note: this is shown for example - find
is not a good name for this function, and this probably will not be needed for all arrays
Instead, consider just using the function definition and creating a function like getObjVal
, calling like getObjVal(arr,'propName')
, similar to LaurenT's answer.
var arr = [{key:'value'},{key2:'value2'}];
// for-loop example
Array.prototype.find = function (prop){
for(var i=this.length; i--; )
if (typeof this[i][prop] !== 'undefined')
return this[i][prop];
return undefined;
}
// for-each loop example
Array.prototype.find = function (prop){
for (var i in this)
if ( this.hasOwnProperty(i) && typeof this[i][prop] !== "undefined" )
return this[i][prop];
return undefined;
}
console.log( arr.find('key2') ); // 'value2'
console.log( arr.find('key3') ); // undefined
Upvotes: 1
Reputation: 110
Try this:
var parsedJSON = JSON.parse(stringJSON);
var value = parsedJSON['key2'];
Upvotes: -1
Reputation: 23002
You can't do it with an array, but you can make an associative array like object with it. Once you make it, you can use it like hash.
var arr = [{key:value},{key2:value2}, ... ], obj = {};
for (var i = 0, len = arr.length; i < len; i++) {
$.extend(obj, arr[i]);
}
console.log(obj.key2); // value2
Upvotes: 2
Reputation: 2778
Regex - no for loop:
var key2Val = jsonString.match(/\{key2:[^\}]+(?=\})/)[0].substring("{key2:".length);
Upvotes: 0
Reputation: 6259
You could use the Select function from the Underscore.js library.
Upvotes: 9