ChatGPT解决这个技术问题 Extra ChatGPT

通过属性值从对象数组中获取JavaScript对象[重复]

这个问题在这里已经有了答案:Find object by id in an array of JavaScript objects (36 answers) 4 年前关闭。

假设我有一个包含四个对象的数组:

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

有没有一种方法可以通过属性 b 的值获取第三个对象 ({a: 5, b: 6}),例如没有 for...in 循环?

是的,这是可能的,只要 b 的值在数组中的所有对象中是唯一的(在本例中就是这样)
@undefined 很确定 op 想要在数组中搜索具有 b = 6 的对象
我喜欢短小精悍并且兼容 pre-ES6 浏览器... jsObjects.find(function(x) {if(xb == 6) return x}) 你可以用它来同时获取属性 a.. .jsObjects.find(function(x) {if(xb == 6) return x}).a

A
Alireza

Filter 对象数组,其属性与值匹配,返回数组:

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

请参阅MDN Docs on Array.prototype.filter()

const jsObjects = [ {a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8} ] 让结果 = jsObjects.filter (obj => { return obj.b === 6 }) console.log(result)

Find 数组中第一个元素/对象的值,否则返回 undefined

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

请参阅MDN Docs on Array.prototype.find()

const jsObjects = [ {a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8} ] 让结果 = jsObjects.find (obj => { return obj.b === 6 }) console.log(result)


这将返回一个数组
@尼克夫。我认为应该,如果有更多具有相同属性的对象怎么办?否则:在这种情况下,result[0] 将是第一个(唯一)对象。
让它返回第一个很容易。在末尾添加“[0]”。 #javaScriptIsAwesome! var result = jsObjects.filter(function( obj ) { return obj.b == 6; })[0];
问题是“获取 JavaScript 对象”,而不是“对象数组”。
@Gothdo 是对的。要获取对象,我们可以使用 Array.find: var result = jsObjects.find(function( obj ) { return obj.b === 6; });
M
Michał Perłakowski
jsObjects.find(x => x.b === 6)

来自 MDN:

如果数组中的元素满足提供的测试函数,则 find() 方法返回数组中的值。否则返回未定义。

旁注:旧版浏览器(如 IE)不支持 find() 和箭头函数等方法,因此如果您想支持这些浏览器,则应使用 Babel 转译您的代码。


请注意,这在 IE 中不受支持
@29er 是的,我写道“并非所有浏览器都支持 find() 和箭头函数之类的方法”。
如果要修改原始数组中的对象,这是最佳选择。 filter() 返回对象的副本,不是原始对象,因此更改不会反映在原始数组中
这并不完全等同于 @elclanrs 使用 filter() 的答案:它只返回第一个匹配项。
@thdoan OP 要求“对象”,而不是“匹配对象的数组”。 elclanrs 的回答是错误的。
A
Aryan

我不知道您为什么反对 for 循环(大概您的意思是 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;
      }
    }
  }
}

哪个是最快的?
到目前为止,For 循环是最快的方法 (jsperf.com/extract-props/1)。
使用 es6 及更高版本:for(let value of arr)
@RobG 将 arr.length 存储在 iLen 中而不是在 for 条件中直接使用 arr.length 作为 i<arr.length 的任何具体原因?
@VikasPrasad - 只是一个小的性能增强,现在可能没有帮助,但在早期它确实有帮助。
R
Rohìt Jíndal

达到要求的方法:

使用 Array.find() 方法:

const jsObject = [ {a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8} ];常量过滤结果 = jsObject.find((e) => eb == 6); console.log(filteredResult);

使用 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) => eb == 6); console.log(filterObj[0]);

使用 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]); } }


A
Alireza

好的,有几种方法可以做到这一点,但让我们从最简单和最新的方法开始,这个函数称为 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}]

谢谢@Alireza。非常完整的答案。至于 .filter 部分: < 此方法将返回一个数组...不是最优雅的解决方案,但考虑在末尾添加 [0] 以便快速修复。 const filterValue = (obj, key, value)=> obj.filter(v => v[key] === value)[0];
M
Megha Karabylu Balaraju

请参阅此文档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 }

不清楚这如何与您调用的“find()”方法一起使用。此外,Internet Explorer 不支持 Object.values()。
好像链接有误。作者可能打算这样做:Array.prototype.find()
如果什么也没找到,这会返回什么? undefined?
@OliverDixon 是的。
m
maia

使用 underscore.js:

var foundObject = _.findWhere(jsObjects, {b: 6});

已弃用。改用 _.findstackoverflow.com/a/40958199/12695188
M
Michał Perłakowski

看起来在 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

n
nickf

如果我理解正确,您想在数组中找到 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;
});

some 只返回 true 或 false,它不返回匹配的对象。
@RobG 是的,很清楚。请注意我如何不从中分配值? :) 它只是在这里被用作短路循环的一种方式。
过于复杂。 .some() 用于确定数组中的某个元素是否通过测试。在这种情况下,最好使用 .forEach(),因为您已经决定将结果分配给一个变量。
@Gothdo 当你已经有了结果时,为什么还要继续循环遍历数组? .some 中的 return true 本质上类似于 for 循环中的 break
S
Sam Dushay

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

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

var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);

S
Shobhit Sharma

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

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}

S
Simple-Solution

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

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} 的第一个对象,另一方面,如果假设您的数组包含多个具有匹配属性集 (key:value) 的对象,那么您应该考虑使用 _.filter() 方法。因此,在您的情况下,由于您的数组有一个具有此属性的对象,因此我将使用 _.find()


A
Andrew

使 this answer 中最好/最快的部分更易于重复使用和清除:

function getElByPropVal(myArray, prop, val){
    for (var i = 0, length = myArray.length; i < length; i++) {
        if (myArray[i][prop] == val){
            return myArray[i];
        }
    }
}

D
Died
var result = jsObjects.filter(x=> x.b === 6);

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


k
kolodi

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

函数 getObjectFromObjectsArrayByPropertyValue(objectsArray, propertyName, propertyValue) { return objectsArray.find(function (objectsArrayElement) { return objectsArrayElement[propertyName] == propertyValue; }); } 函数 findObject () { var arrayOfObjectsString = document.getElementById("arrayOfObjects").value, arrayOfObjects, propertyName = document.getElementById("propertyName").value, propertyValue = document.getElementById("propertyValue").value, preview = document.getElementById("preview"), 搜索对象; arrayOfObjects = JSON.parse(arrayOfObjectsString); console.debug(arrayOfObjects); if(arrayOfObjects && propertyName && propertyValue) { searchObject = getObjectFromObjectsArrayByPropertyValue(arrayOfObjects, propertyName, propertyValue); if(searchingObject) { preview.innerHTML = JSON.stringify(searchingObject, false, 2); } else { preview.innerHTML = "您的对象数组中没有具有属性的对象 " + propertyName + " = " + propertyValue + ""; } } } pre { 填充:5px;边框半径:4px;背景:#f3f2f2; } textarea, button { width: 100% }

Input Data:


搜索结果:
点击查找


S
Serjuice

使用 find 和 bind 将特定的键值传递给回调函数。

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

   var result = jsObjects.find(byValue.bind({ a: 5, b: 6 }));

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

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