在Javascript中的对象数组中查找值[重复]

Posted

技术标签:

【中文标题】在Javascript中的对象数组中查找值[重复]【英文标题】:Find a value in an array of objects in Javascript [duplicate] 【发布时间】:2012-09-09 20:23:50 【问题描述】:

我知道以前有人问过类似的问题,但这个问题有点不同。我有一个未命名对象数组,其中包含一个命名对象数组,我需要获取“名称”为“字符串 1”的对象。这是一个示例数组。

var array = [
     name:"string 1", value:"this", other: "that" ,
     name:"string 2", value:"this", other: "that" 
];

更新:我应该早点说,但是一旦我找到它,我想用一个编辑过的对象替换它。

【问题讨论】:

如果你知道它在哪里,你可以用array[0]['name'] 【参考方案1】:

查找数组元素:

let arr = [
     name:"string 1", value:"this", other: "that" ,
     name:"string 2", value:"this", other: "that" 
];

let obj = arr.find(o => o.name === 'string 1');

console.log(obj);

替换数组元素:

let arr = [
     name:"string 1", value:"this", other: "that" ,
     name:"string 2", value:"this", other: "that" 
];

let obj = arr.find((o, i) => 
    if (o.name === 'string 1') 
        arr[i] =  name: 'new string', value: 'this', other: 'that' ;
        return true; // stop searching
    
);

console.log(arr);

【讨论】:

对于第二个示例,您应该将arr 作为回调函数的第三个参数。这就是它的意义所在。 @AaditMShah 我想知道这有什么意义。 arr 变量已在外部作用域中可用。 两个原因。首先,arr 变量可能并不总是在外部作用域中可用。其次,它更快,因为它是一个局部变量。 @AaditMShah 如果没有变量,那么是的,第三个参数可能很有用。但是由于在这种情况下我们有变量,所以不需要它。关于第二点,在实践中并不快。 1 微秒的改进甚至不值得谈论,更不用说为它创建代码了,恕我直言。 @nishant 不需要。 find 方法自动为每个数组元素调用该函数,直到返回 truthy 值。所以如果函数没有返回任何东西,返回值是undefined,这不是truthy,所以函数正常调用下一个元素。【参考方案2】:

您可以遍历数组并测试该属性:

function search(nameKey, myArray)
    for (var i=0; i < myArray.length; i++) 
        if (myArray[i].name === nameKey) 
            return myArray[i];
        
    


var array = [
     name:"string 1", value:"this", other: "that" ,
     name:"string 2", value:"this", other: "that" 
];

var resultObject = search("string 1", array);

【讨论】:

将函数更改为search(nameKey, prop, myArray),将if 子句更改为if (myArray[i][prop]=== nameKey) ,然后搜索对象内的任何属性 还有一个小工具可以解决这个问题,叫做super-array 如果是整数值,使用==【参考方案3】:

ES6 中,您可以像这样使用Array.prototype.find(predicate, thisArg?)

array.find(x => x.name === 'string 1')

http://exploringjs.com/es6/ch_arrays.html#_searching-for-array-elements https://developer.mozilla.org/en/docs/Web/javascript/Reference/Global_Objects/Array/find

然后替换所述对象(并使用另一个很酷的 ES6 方法fill),您可以执行以下操作:

let obj = array.find(x => x.name === 'string 1');
let index = array.indexOf(obj);
array.fill(obj.name='some new string', index, index++);

【讨论】:

我在搜索如何在 Angular2 模板中使用 find 设置属性时碰巧找到了这个答案。最后这篇文章很好地结合了 ES6 find 和管道...***.com/questions/35986017/… 如果只是一个值,这里也可以简写为:array.find(x => x.name === "string 1").name = "some new string" ; 谢谢你!!!!能够使用此代码从字面上找到数组中的某些内容,然后将其取出名称并使用变量...我将在下面发布我的答案 已经有 findIndex 方法可用,它返回索引而不是对象,这使您免于再次使用 indexOf 我只能使用 == 来完成这项工作,而不是 ===【参考方案4】:

根据 ECMAScript 6,您可以使用 findIndex 函数。

array[array.findIndex(x => x.name == 'string 1')]

【讨论】:

findIndex 是正确的解决方案。当然不是foreach里面的foreach。这应该被接受的答案 这个方案效果很好,简洁干净! 在 ES6 中,.find() 会直接返回元素。不需要使用.findIndex() 获取索引,然后通过索引获取元素。【参考方案5】:
var array = [
     name:"string 1", value:"this", other: "that" ,
     name:"string 2", value:"this", other: "that" 
];

var foundValue = array.filter(obj=>obj.name==='string 1');

console.log(foundValue);

【讨论】:

'find' 是比 'filter' 更好的选择来查找特定对象 为什么要找到更好的选择,并且能够帮助找到特定的对象?不同之处在于它获取第一个对象与返回所有结果。 find 不会告诉你有多少结果与字符串匹配。反之filter支持IE,find不支持 filter的问题是它返回的是一个数组,而不是值! 我一直在寻找这种答案而不是***答案。 tnx :) find() 方法返回集合中匹配的第一个值。一旦它与结果中的值匹配,它将不会检查数组集合中的剩余值。 filter() 方法从集合中返回数组中匹配的值。【参考方案6】:

考虑到你有以下 sn-p:

var array = [
     name:"string 1", value:"this", other: "that" ,
     name:"string 2", value:"this", other: "that" 
];

您可以使用以下功能来搜索物品

const search = what => array.find(element => element.name === what);

您可以检查该项目是否被发现。

if (search("string 1")) 
    console.log(search.value, search.other);
 else 
    console.log('No result found');

【讨论】:

search.valuesearch.other 未定义。 search在你的代码中不是对象而是返回对象的函数。 const serached = search("string 1"); if (serached) console.log(serached.name, serached.value, serached.other); else console.log('未找到结果'); 更好的解决方案: const search = (what, arr) => arr.find(element => element[what.split(':')[0]] === what.split( ':')[1]); const serached = search("value:string 1",array); if (serached) console.log(serached.name, serached.value, serached.other); else console.log('未找到结果'); 【参考方案7】:

使用 foreach:

let itemYouWant = null;
array.forEach((item) => 
    if (item.name === 'string 1') 
        itemYouWant = item;
    
);
console.log(itemYouWant);

【讨论】:

你不能从 foreach 循环中返回,它会迭代所有项目,不管你放什么条件。 @ShashankGaurav 你说得对,我在函数中使用了我的示例。所以我更新了我的答案。感谢您的反馈!【参考方案8】:

要么使用简单的for-loop:

var result = null;
for (var i = 0; i < array.length; i++)  
  if (array[i].name === "string 1")  
    result = array[i];
    break;
   

或者如果可以的话,也就是如果你的浏览器支持的话,使用Array.filter,这样更简洁:

var result = array.filter(function (obj) 
  return obj.name === "string 1";
)[0];

【讨论】:

当obj返回时,如何获取它在原始数组中的位置? @VedranMaricevic。使用 array.fill()【参考方案9】:

underscore.js 一起使用 findWhere 方法:

var array = [
     name:"string 1", value:"this", other: "that" ,
     name:"string 2", value:"this", other: "that" 
];


var result = _.findWhere(array, name: 'string 1');

console.log(result.name);

在JSFIDDLE看到这个

【讨论】:

如果您需要知道数组索引(不仅仅是匹配对象),您可以将 _.findWhere() 与 _.indexOf() 混合,如下所示:var index = _.indexOf(array, _.findWhere(array, name: 'string 1')); @James 似乎很浪费,因为这将不得不遍历数组两次。另外,此时您并没有从下划线中获得任何代码清晰度。如果您要使用它,最好只编写您自己的名称函数。【参考方案10】:

一行答案。 您可以使用过滤功能来获取结果。

var array = [
     name:"string 1", value:"this", other: "that" ,
     name:"string 2", value:"this", other: "that" 
];

console.log(array.filter(function(arr)return arr.name == 'string 1')[0]);

【讨论】:

【参考方案11】:

新答案

我将 prop 添加为参数,使其更通用和可重用

/**
 * Represents a search trough an array.
 * @function search
 * @param Array array - The array you wanna search trough
 * @param string key - The key to search for
 * @param string [prop] - The property name to find it in
 */

function search(array, key, prop)
    // Optional, but fallback to key['name'] if not selected
    prop = (typeof prop === 'undefined') ? 'name' : prop;    

    for (var i=0; i < array.length; i++) 
        if (array[i][prop] === key) 
            return array[i];
        
    

用法:

var array = [
     
        name:'string 1', 
        value:'this', 
        other: 'that' 
    ,
     
        name:'string 2', 
        value:'this', 
        other: 'that' 
    
];

search(array, 'string 1');
// or for other cases where the prop isn't 'name'
// ex: prop name id
search(array, 'string 1', 'id');

摩卡测试:

var assert = require('chai').assert;

describe('Search', function() 
    var testArray = [
         
            name: 'string 1', 
            value: 'this', 
            other: 'that' 
        ,
         
            name: 'string 2', 
            value: 'new', 
            other: 'that' 
        
    ];

    it('should return the object that match the search', function () 
        var name1 = search(testArray, 'string 1');
        var name2 = search(testArray, 'string 2');

        assert.equal(name1, testArray[0]);
        assert.equal(name2, testArray[1]);

        var value1 = search(testArray, 'this', 'value');
        var value2 = search(testArray, 'new', 'value');

        assert.equal(value1, testArray[0]);
        assert.equal(value2, testArray[1]);
    );

    it('should return undefined becuase non of the objects in the array have that value', function () 
        var findNonExistingObj = search(testArray, 'string 3');

        assert.equal(findNonExistingObj, undefined);
    );

    it('should return undefined becuase our array of objects dont have ids', function () 
        var findById = search(testArray, 'string 1', 'id');

        assert.equal(findById, undefined);
    );
);

测试结果:

Search
    ✓ should return the object that match the search
    ✓ should return undefined becuase non of the objects in the array have that value
    ✓ should return undefined becuase our array of objects dont have ids


  3 passing (12ms)

旧答案 - 由于不良做法而被删除

如果您想了解更多为什么这是不好的做法,请参阅这篇文章:

Why is extending native objects a bad practice?

进行数组搜索的原型版本:

Array.prototype.search = function(key, prop)
    for (var i=0; i < this.length; i++) 
        if (this[i][prop] === key) 
            return this[i];
        
    

用法:

var array = [
     name:'string 1', value:'this', other: 'that' ,
     name:'string 2', value:'this', other: 'that' 
];

array.search('string 1', 'name');

【讨论】:

你不应该修改原生对象的原型。谷歌一下为什么这很糟糕,有很多文章和 *** 问题。这个问题的答案给出了一个很好的理由(***.com/questions/3010840/…) 到目前为止对我来说效果很好,但它可能是一种反模式 它确实有效,但它是一种反模式和不好的做法 @silverlight513 还添加了 mocha 测试和结果 +1 用于添加测试,它们总是值得添加的东西。我不得不说,Šime Vidas 对过滤器的使用似乎是一种更简洁的方式,可以通过数组循环查找对象 (imo)。【参考方案12】:

你可以用一个简单的循环来做到这一点:

var obj = null;    
for (var i = 0; i < array.length; i++) 
    if (array[i].name == "string 1") 
        obj = array[i];
        break;
    

【讨论】:

空对象有什么用? @Bergi 这取决于代码的用途。那么null呢? 对我来说更有意义,谢谢。只要undefined 也可以,恕我直言…… @Bergi 也许null 对于未找到的元素更具描述性。【参考方案13】:

另一种方法(帮助@NullUserException 和@Wexoni 的cmets)是在数组中检索对象的索引,然后从那里开始:

var index = array.map(function(obj) return obj.name; ).indexOf('name-I-am-looking-for');
// Then we can access it to do whatever we want
array[index] = name: 'newName', value: 'that', other: 'rocks';

【讨论】:

【参考方案14】:

与之前的答案类似,我使用了以下内容:

    Array.prototype.getIemtByParam = function(paramPair) 
      var key = Object.keys(paramPair)[0];
      return this.find(function(item)return ((item[key] == paramPair[key]) ? true: false));
    

用法:

myArray.getIemtByParam(
    name: 'Sasha'
);

【讨论】:

【参考方案15】:

这里是搜索和替换的解决方案

function searchAndUpdate(name,replace)
    var obj = array.filter(function ( obj ) 
        return obj.name === name;
    )[0];
    obj.name = replace;


searchAndUpdate("string 2","New String 2");

【讨论】:

【参考方案16】:

您是否在对象列表中的项目中寻找通用搜索(过滤器)而不指定项目键

输入

var productList = [category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football', category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball', category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball', category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch', category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5', category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7']
function customFilter(objList, text)
if(undefined === text || text === '' ) return objList;
return objList.filter(product => 
    let flag;
    for(let prop in product)
        flag = false;
        flag = product[prop].toString().indexOf(text) > -1;
        if(flag)
        break;
    
return flag;
);

执行

customFilter(productList, '$9');

【讨论】:

这很好用。如何使它适用于嵌套对象? ***.com/questions/44550439/…【参考方案17】:

如果你使用 jQuery,试试 $.grep()。

http://api.jquery.com/jquery.grep/

【讨论】:

【参考方案18】:

你可以使用来自 npm 的query-objects。您可以使用过滤器搜索对象数组。

const queryable = require('query-objects');

const users = [
    
      firstName: 'George',
      lastName: 'Eracleous',
      age: 28
    ,
    
      firstName: 'Erica',
      lastName: 'Archer',
      age: 50
    ,
    
      firstName: 'Leo',
      lastName: 'Andrews',
      age: 20
    
];

const filters = [
    
      field: 'age',
      value: 30,
      operator: 'lt'
    ,
    
      field: 'firstName',
      value: 'Erica',
      operator: 'equals'
    
];

// Filter all users that are less than 30 years old AND their first name is Erica
const res = queryable(users).and(filters);

// Filter all users that are less than 30 years old OR their first name is Erica
const res = queryable(users).or(filters);

【讨论】:

【参考方案19】:
function getValue()
    for(var i = 0 ; i< array.length; i++)
        var obj = array[i];
        var arr = array["types"];
        for(var j = 0; j<arr.length;j++ )
            if(arr[j] == "value")
                return obj;
            
        

    

【讨论】:

【参考方案20】:

此答案适用于 typescript / Angular 2、4、5+

我在上面的@rujmah 答案的帮助下得到了这个答案。他的回答带来了数组计数...然后找到值并将其替换为另一个值...

这个答案所做的只是获取可能通过另一个模块/组件在另一个变量中设置的数组名称......在这种情况下,我构建的数组有一个 css 名称为stay-dates。所以它的作用是提取该名称,然后允许我将其设置为另一个变量并像这样使用它。就我而言,它是一个 html css 类。

let obj = this.highlightDays.find(x => x.css); let index = this.highlightDays.indexOf(obj); console.log('here we see what hightlightdays is ', obj.css); let dayCss = obj.css;

【讨论】:

以上是关于在Javascript中的对象数组中查找值[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中的对象数组中查找值?

根据JavaScript中的属性值从对象数组中选择[重复]

如何在javascript中查找重复值并将重复值存储到新数组中

将javascript数组中的重复值分组在一起,然后按值名称升序对这些组进行排序

NodeJS / Javascript在不同数组中查找具有相同属性的对象

如果对象数组中两个不同对象的两个键在JavaScript中相同,则通过键查找对象[重复]