简体   繁体   中英

Best way of basically doing a `where` clause in Javascript?

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?

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");

您可以使用Underscore.js库中的Select函数。

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}]

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"))

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 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;
                       }

Usage


console.log( arr.find('key2') );  // 'value2'
console.log( arr.find('key3') );  // undefined

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.

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.

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;

正则表达式 - 没有 for 循环:

var key2Val = jsonString.match(/\{key2:[^\}]+(?=\})/)[0].substring("{key2:".length);

Try this:

var parsedJSON = JSON.parse(stringJSON);
var value = parsedJSON['key2'];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM