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?
Best Answer
You could use the Select function from the Underscore.js library.
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");
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"))
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}]
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
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.
Given
var arr = [{key:'value'},{key2:'value2'}];
Definition
// for-loop exampleArray.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 exampleArray.prototype.find = function (prop){for (var i in this)if ( this.hasOwnProperty(i) && typeof this[i][prop] !== "undefined" ) return this[i][prop];return undefined;}
Usage
console.log( arr.find('key2') ); // 'value2'console.log( arr.find('key3') ); // undefined
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;
Regex - no for loop:
var key2Val = jsonString.match(/\{key2:[^\}]+(?=\})/)[0].substring("{key2:".length);
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.
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.
Try this:
var parsedJSON = JSON.parse(stringJSON);var value = parsedJSON['key2'];