1123

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?

4

17 回答 17

1588

Filter array of objects, which property matches value, returns array:

var result = jsObjects.filter(obj => {
  return obj.b === 6
})

See the MDN Docs on Array.prototype.filter()

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

let result = jsObjects.filter(obj => {
  return obj.b === 6
})

console.log(result)

Find the value of the first element/object in the array, otherwise undefined is returned.

var result = jsObjects.find(obj => {
  return obj.b === 6
})

See the MDN Docs on Array.prototype.find()

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

let result = jsObjects.find(obj => {
  return obj.b === 6
})

console.log(result)

于 2012-12-20T02:01:22.363 回答
415
jsObjects.find(x => x.b === 6)

来自 MDN:

find()如果数组中的元素满足提供的测试功能,则该方法返回数组中的值。否则undefined返回。


旁注:find()旧浏览器(如 IE)不支持方法和箭头函数,所以如果你想支持这些浏览器,你应该使用Babel转译你的代码。

于 2016-02-14T20:51:13.230 回答
189

我不知道您为什么反对 for 循环(大概您的意思是 a for loop,而不是专门的for..in),它们快速且易于阅读。无论如何,这里有一些选择。

对于循环:

function getByValue(arr, value) {

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

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

。筛选

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

}

另一方面,如果您确实是指 for..in 并且想要查找具有任何值为 6 的属性的对象,那么您必须使用 for..in 除非您将名称传递给检查。

例子

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;
      }
    }
  }
}
于 2012-12-20T02:58:29.240 回答
46

达到要求的方法:

  1. 使用Array.find()方法

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

const filteredResult = jsObject.find((e) => e.b == 6);

console.log(filteredResult);

  1. 使用Array.filter()方法

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

const filterObj = jsObjects.filter((e) => e.b == 6);

console.log(filterObj[0]);

  1. 使用for...in循环

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

for (const i in jsObjects) {
  if (jsObjects[i].b == 6) {
    console.log(jsObjects[i]);
  }
}

于 2016-11-02T09:57:55.620 回答
31

好的,有几种方法可以做到这一点,但让我们从最简单和最新的方法开始,这个函数被称为find().

使用时要小心find,因为即使 IE11 也不支持它,所以它需要被转译......

所以你有这个对象,正如你所说:

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

你可以编写一个函数并像这样得到它:

function filterValue(obj, key, value) {
  return obj.find(function(v){ return v[key] === value});
}

并使用这样的功能:

filterValue(jsObjects, "b", 6); //{a: 5, b: 6}

同样在ES6中用于更短的版本:

const filterValue = (obj, key, value)=> obj.find(v => v[key] === value);

此方法仅返回匹配的第一个值...,为了更好的结果和浏览器支持,您可以使用filter

const filterValue = (obj, key, value)=> obj.filter(v => v[key] === value);

我们将返回[{a: 5, b: 6}]...

此方法将返回一个数组而不是...

您也可以简单地使用 for 循环,创建一个这样的函数:

function filteredArray(arr, key, value) {
  const newArray = [];
  for(i=0, l=arr.length; i<l; i++) {
    if(arr[i][key] === value) {
      newArray.push(arr[i]);
    }
  }
 return newArray;
}

并这样称呼它:

filteredArray(jsObjects, "b", 6); //[{a: 5, b: 6}]
于 2018-03-30T05:38:53.110 回答
26

请参阅本文档Array.prototype.find()

例子:

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 }
于 2017-09-07T11:35:50.667 回答
22

Using underscore.js:

var foundObject = _.findWhere(jsObjects, {b: 6});
于 2015-10-16T18:15:36.910 回答
20

看起来在 ECMAScript 6 提案中有Array方法find()findIndex(). MDN 还提供了 polyfill,您可以将其包含在内以在所有浏览器中获取这些功能。

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
于 2014-04-04T07:39:54.980 回答
18

如果我理解正确,您想在数组中找到b属性为的对象6

var found;
jsObjects.some(function (obj) {
  if (obj.b === 6) {
    found = obj;
    return true;
  }
});

或者,如果您使用下划线:

var found = _.select(jsObjects, function (obj) {
  return obj.b === 6;
});
于 2012-12-20T02:03:03.060 回答
17

如果您正在寻找单个结果而不是数组,我可以建议减少吗?

这是一个简单的 'ole javascript 解决方案,如果存在则返回匹配的对象,如果不存在则返回 null。

var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);
于 2015-12-08T17:10:22.203 回答
14

您可以将它与箭头功能一起使用,如下所示:

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

var result = demoArray.filter( obj => obj.name === 'apples')[0];
console.log(result);
// {name: 'apples', quantity: 2}
于 2018-01-16T08:07:58.103 回答
11

如何使用_.find(collection, [predicate=_.identity], [fromIndex=0])lo -dash通过对象属性值从对象数组中获取对象。你可以这样做:

var o = _.find(jsObjects, {'b': 6});

论据:

collection (Array|Object): The collection to inspect.
[predicate=_.identity] (Function): The function invoked per iteration.
[fromIndex=0] (number): The index to search from.

退货

(*): Returns the matched element (in your case, {a: 5, b: 6}), else undefined.

在性能方面,_.find()它更快,因为它只提取第一个具有属性的对象,{'b': 6}另一方面,如果假设您的数组包含多个具有匹配属性集(键:值)的对象,那么您应该考虑使用_.filter()方法。因此,在您的情况下,由于您的数组具有具有此属性的单个对象,因此我将使用_.find().

于 2016-12-04T11:37:58.360 回答
8

使这个答案中最好/最快的部分更加可重用和清晰:

function getElByPropVal(myArray, prop, val){
    for (var i = 0, length = myArray.length; i < length; i++) {
        if (myArray[i][prop] == val){
            return myArray[i];
        }
    }
}
于 2018-02-15T19:31:02.777 回答
6
var result = jsObjects.filter(x=> x.b === 6);

会更好,在过滤器中使用 return 有时你不能得到结果(我不知道为什么)

于 2018-02-09T08:18:14.867 回答
3

通过特定属性值从对象数组中获取第一个对象:

function getObjectFromObjectsArrayByPropertyValue(objectsArray, propertyName, propertyValue) {
  return objectsArray.find(function (objectsArrayElement) {
    return objectsArrayElement[propertyName] == propertyValue;
  });
}

function findObject () {
  var arrayOfObjectsString = document.getElementById("arrayOfObjects").value,
      arrayOfObjects,
      propertyName = document.getElementById("propertyName").value,
      propertyValue = document.getElementById("propertyValue").value,
      preview = document.getElementById("preview"),
      searchingObject;
  
  arrayOfObjects = JSON.parse(arrayOfObjectsString);
  
  console.debug(arrayOfObjects);
  
  if(arrayOfObjects && propertyName && propertyValue) {
    searchingObject = getObjectFromObjectsArrayByPropertyValue(arrayOfObjects, propertyName, propertyValue);
    if(searchingObject) {
      preview.innerHTML = JSON.stringify(searchingObject, false, 2);
    } else {
      preview.innerHTML = "there is no object with property " + propertyName + " = " + propertyValue + " in your array of objects";
    }
  }
}
pre {
  padding: 5px;
  border-radius: 4px;
  background: #f3f2f2;
}

textarea, button {
  width: 100%
}
<fieldset>
  <legend>Input Data:</legend>
  <label>Put here your array of objects</label>
  <textarea rows="7" id="arrayOfObjects">
  [
    {"a": 1, "b": 2},
    {"a": 3, "b": 4},
    {"a": 5, "b": 6},
    {"a": 7, "b": 8, "c": 157}
  ]
  </textarea>

  <hr>

  <label>property name: </label> <input type="text" id="propertyName"  value="b"/>
  <label>property value: </label> <input type="text" id="propertyValue" value=6 />
     
</fieldset>
<hr>
<button onclick="findObject()">find object in array!</button>
<hr>
<fieldset>
  <legend>Searching Result:</legend>
  <pre id="preview">click find</pre>
</fieldset>

于 2016-04-27T10:08:42.703 回答
2

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 }));
于 2017-04-10T12:26:19.703 回答
-31
var jsObjects = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8}];

要访问第三个对象,请使用:jsObjects[2];
要访问第三个对象 b 值,请使用:jsObjects[2].b;

于 2015-07-23T04:54:33.383 回答