Get JavaScript object from array of objects by val

2018-12-31 03:23发布

This question already has an answer here:

Let's say I have an array of four objects:

var jsObjects = [
   {a: 1, b: 2}, 
   {a: 3, b: 4}, 
   {a: 5, b: 6}, 
   {a: 7, b: 8}
];

Is there a way that I can get the third object ({a: 5, b: 6}) by the value of the property b for example without a for...in loop?

17条回答
余欢
2楼-- · 2018-12-31 04:07

If you are looking for a single result, rather than an array, may I suggest reduce?

Here is a solution in plain 'ole javascript that returns a matching object if one exists, or null if not.

var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);
查看更多
姐姐魅力值爆表
3楼-- · 2018-12-31 04:07

See this documentation https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
Example :

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5}
];

function findCherries(fruit) { 
    return fruit.name === 'cherries';
}

console.log(inventory.find(findCherries)); 
// { name: 'cherries', quantity: 5 }
查看更多
几人难应
4楼-- · 2018-12-31 04:11

Using underscore.js:

var foundObject = _.findWhere(jsObjects, {b: 6});
查看更多
墨雨无痕
5楼-- · 2018-12-31 04:11

It looks like in the ECMAScript 6 proposal there are the Array methods find() and findIndex(). MDN also offers polyfills which you can include to get the functionality of these across all browsers.

find():

function isPrime(element, index, array) {
    var start = 2;
    while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) return false;
    }
    return (element > 1);
}

console.log( [4, 6, 8, 12].find(isPrime) ); // undefined, not found
console.log( [4, 5, 8, 12].find(isPrime) ); // 5

findIndex():

function isPrime(element, index, array) {
    var start = 2;
    while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) return false;
    }
    return (element > 1);
}

console.log( [4, 6, 8, 12].findIndex(isPrime) ); // -1, not found
console.log( [4, 6, 7, 12].findIndex(isPrime) ); // 2
查看更多
低头抚发
6楼-- · 2018-12-31 04:13

Using find with bind to pass specific key values to a callback function.

   function byValue(o) { 
       return o.a === this.a && o.b === this.b; 
   };   

   var result = jsObjects.find(byValue.bind({ a: 5, b: 6 }));
查看更多
梦醉为红颜
7楼-- · 2018-12-31 04:14

I don't know why you are against a for loop (presumably you meant a for loop, not specifically for..in), they are fast and easy to read. Anyhow, here's some options.

For loop:

function getByValue(arr, value) {

  for (var i=0, iLen=arr.length; i<iLen; i++) {

    if (arr[i].b == value) return arr[i];
  }
}

.filter

function getByValue2(arr, value) {

  var result  = arr.filter(function(o){return o.b == value;} );

  return result? result[0] : null; // or undefined

}

.forEach

function getByValue3(arr, value) {

  var result = [];

  arr.forEach(function(o){if (o.b == value) result.push(o);} );

  return result? result[0] : null; // or undefined

}

If, on the other hand you really did mean for..in and want to find an object with any property with a value of 6, then you must use for..in unless you pass the names to check. e.g.

function getByValue4(arr, value) {
  var o;

  for (var i=0, iLen=arr.length; i<iLen; i++) {
    o = arr[i];

    for (var p in o) {
      if (o.hasOwnProperty(p) && o[p] == value) {
        return o;
      }
    }
  }
}
查看更多
登录 后发表回答