Javascript 如何判断对象是否在数组中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4587061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 13:06:05  来源:igfitidea点击:

How to determine if object is in array

javascript

提问by Caspar Kleijne

I need to determine if an object already exists in an array in javascript.

我需要确定一个对象是否已经存在于 javascript 的数组中。

eg (dummycode):

例如(虚拟代码):

var carBrands = [];

var car1 = {name:'ford'};
var car2 = {name:'lexus'};
var car3 = {name:'maserati'};
var car4 = {name:'ford'};

carBrands.push(car1);
carBrands.push(car2);
carBrands.push(car3);
carBrands.push(car4);

now the "carBrands" array contains all instances. I'm now looking a fast solution to check if an instance of car1, car2, car3 or car4 is already in the carBrands array.

现在“carBrands”数组包含所有实例。我现在正在寻找一种快速解决方案来检查 car1、car2、car3 或 car4 的实例是否已经在 carBrands 数组中。

eg:

例如:

var contains =  carBrands.Contains(car1); //<--- returns bool.

car1 and car4 contain the same data but are different instances they should be tested as not equal.

car1 和 car4 包含相同的数据,但它们是不同的实例,它们应该被测试为不相等。

Do I have add something like a hash to the objects on creation? Or is there a faster way to do this in Javascript.

我是否在创建时向对象添加了哈希之类的东西?或者在 Javascript 中有更快的方法来做到这一点。

I am looking for the fastest solution here, if dirty, so it has to be ;) In my app it has to deal with around 10000 instances.

我在这里寻找最快的解决方案,如果脏,所以它必须是 ;) 在我的应用程序中,它必须处理大约 10000 个实例。

no jquery

没有jQuery

采纳答案by cdhowie

Use something like this:

使用这样的东西:

function containsObject(obj, list) {
    var i;
    for (i = 0; i < list.length; i++) {
        if (list[i] === obj) {
            return true;
        }
    }

    return false;
}

In this case, containsObject(car4, carBrands)is true. Remove the carBrands.push(car4);call and it will return false instead. If you later expand to using objects to store these other car objects instead of using arrays, you could use something like this instead:

在这种情况下,containsObject(car4, carBrands)是真的。删除carBrands.push(car4);调用,它将返回 false。如果您以后扩展到使用对象来存储这些其他汽车对象而不是使用数组,则可以使用以下内容:

function containsObject(obj, list) {
    var x;
    for (x in list) {
        if (list.hasOwnProperty(x) && list[x] === obj) {
            return true;
        }
    }

    return false;
}

This approach will work for arrays too, but when used on arrays it will be a tad slower than the first option.

这种方法也适用于数组,但在数组上使用时,它会比第一个选项慢一点。

回答by Frax

Why don't you use the indexOfmethod of javascript arrays?

为什么不使用javascript 数组的indexOf方法?

Check this out: MDN indexOf Arrays

看看这个:MDN indexOf Arrays

Simply do:

简单地做:

carBrands.indexOf(car1);

It will return you the index (position in the array) of car1. It will return -1 if car1 was not found in the array.

它将返回 car1 的索引(数组中的位置)。如果在数组中找不到 car1,它将返回 -1。

http://jsfiddle.net/Fraximus/r154cd9o

http://jsfiddle.net/Fraximus/r154cd9o

Edit:Note that in the question, the requirements are to check for the same object referenced in the array, and NOT a new object. Even if the new object is identical in content to the object in the array, it is still a different object. As mentioned in the comments, objects are passed by reference in JS and the same object can exist multiple times in multiple structures.
If you want to create a new object and check if the array contains objects identical to your new one, this answer won't work (Julien's fiddle below), if you want to check for that same object's existence in the array, then this answer will work. Check out the fiddles here and in the comments.

编辑:请注意,在问题中,要求是检查数组中引用相同对象,而不是新对象。即使新对象的内容与数组中的对象相同,它仍然是不同的对象。正如评论中提到的,对象在 JS 中是通过引用传递的,并且同一个对象可以在多个结构中多次存在。
如果您想创建一个新对象并检查数组是否包含与您的新对象相同的对象,则此答案将不起作用(下面 Julien 的小提琴),如果您想检查数组中是否存在相同的对象,则此答案将工作。在此处和评论中查看小提琴。

回答by Faktor 10

Having been recently bitten by the FP bug reading many wonderful accounts of how neatly the functional paradigm fits with Javascript

最近被 FP 错误所困扰,阅读了许多关于函数范式与 Javascript 完美契合的精彩描述

I replicate the code for completeness sake and suggest two ways this can be done functionally.

为了完整起见,我复制了代码并建议了两种可以在功能上完成的方法。

    var carBrands = [];

  var car1 = {name:'ford'};
  var car2 = {name:'lexus'};
  var car3 = {name:'maserati'};
  var car4 = {name:'ford'};
  var car5 = {name:'toyota'};

  carBrands.push(car1);
  carBrands.push(car2);
  carBrands.push(car3);
  carBrands.push(car4);

  // ES6 approach which uses the includes method (Chrome47+, Firefox43+)

  carBrands.includes(car1) // -> true
  carBrands.includes(car5) // -> false

If you need to support older browsers use the polyfill, it seems IE9+ and Edge do NOT support it. Located in polyfill section of MSDN page

如果你需要支持旧浏览器使用 polyfill,IE9+ 和 Edge 似乎不支持它。位于MSDN 页面的 polyfill 部分

Alternatively I would like to propose an updated answer to cdhowie

或者,我想向cdhowie提出更新的答案

// ES2015 syntax
function containsObject(obj, list) {

    return list.some(function(elem) {
      return elem === obj
    })
}

// or ES6+ syntax with cool fat arrows
function containsObject(obj, list) {

    return list.some(elem => elem === obj)
}

回答by stef

You could use jQuery's grepmethod:

您可以使用jQuery 的 grep方法:

$.grep(carBrands, function(obj) { return obj.name == "ford"; });

But as you specify no jQuery, you could just make a derivative of the function. From the source code:

但是当您没有指定 jQuery 时,您可以只对函数进行派生。从源代码:

function grepArray( elems, callback, inv ) {  
    var ret = [];  

    // Go through the array, only saving the items  
    // that pass the validator function  
    for ( var i = 0, length = elems.length; i < length; i++ ) {  
        if ( !inv !== !callback( elems[ i ], i ) ) {  
            ret.push( elems[ i ] );  
        }  
    }  

    return ret;  
}  

grepArray(carBrands, function(obj) { return obj.name == "ford"; });

回答by UtillYou

try Array.prototype.some()

尝试 Array.prototype.some()

MDN Array.prototype.some

MDN Array.prototype.some


    function isBiggerThan10(element, index, array) {
      return element > 10;
    }
    [2, 5, 8, 1, 4].some(isBiggerThan10);  // false
    [12, 5, 8, 1, 4].some(isBiggerThan10); // true

回答by zzzzBov

You can just use the equality operator: ==. Objects are checked by reference by default, so you don't even need to use the ===operator.

您可以只使用相等运算符:==。默认情况下通过引用检查对象,因此您甚至不需要使用===运算符。

try this, just make sure you're using the correct variable reference in the place of car1:

试试这个,只需确保您使用正确的变量引用代替car1

var i, car, l = cars.length;

for (i = 0; i < l; i++)
{
  if ((car = cars[i]) == car1)
  {
    break;
  }
  else car = null;
}

Edit to add:

编辑添加:

An array extension was mentioned, so here's the code for it:

提到了一个数组扩展,所以这里是它的代码:

Array.prototype.contains = Array.prototype.contains || function(obj)
{
  var i, l = this.length;
  for (i = 0; i < l; i++)
  {
    if (this[i] == obj) return true;
  }
  return false;
};

Note that I'm caching the length value, as the Array's lengthproperty is actually an accessor, which is marginally slower than an internal variable.

请注意,我正在缓存长度值,因为 Array 的length属性实际上是一个访问器,它比内部变量稍微慢一些。

回答by Jinesh

I used underscorejavascript library to tweak this issue.

我使用underscorejavascript 库来调整这个问题。

function containsObject(obj, list) {
 var res = _.find(list, function(val){ return _.isEqual(obj, val)});
 return (_.isObject(res))? true:false;
}

please refer to underscore.jsdocumentation for the underscore functions used in the above example.

上面例子中使用的下划线函数请参考underscore.js文档。

note: This is not a pure javascript solution. Shared for educational purposes.

注意:这不是纯 javascript 解决方案。出于教育目的共享。

回答by Deiu

I would use a generic iterator of property/value over the array. No jQuery required.

我会在数组上使用属性/值的通用迭代器。不需要jQuery。

arr = [{prop1: 'val1', prop2: 'val2'}, {prop1: 'val3', prop2: 'val4'}];

objectPropInArray(arr, 'prop1', 'val3'); // <-- returns true

function objectPropInArray(list, prop, val) {
  if (list.length > 0 ) {
    for (i in list) {
      if (list[i][prop] === val) {
        return true;
      }
    }
  }
  return false;  
}

回答by Robusto

You could try sorting the array based on a property, like so:

您可以尝试根据属性对数组进行排序,如下所示:

carBrands = carBrands.sort(function(x,y){
  return (x == y) ? 0 : (x > y) ? 1 : -1;
});

Then you can use an iterative routine to check whether

然后您可以使用迭代例程来检查是否

carBrands[Math.floor(carBrands.length/2)] 
// change carBrands.length to a var that keeps 
// getting divided by 2 until result is the target 
// or no valid target exists

is greater or lesser than the target, and so on, which will let you go through the array quickly to find whether the object exists or not.

大于或小于目标,等等,这样可以让你快速遍历数组,查找对象是否存在。

回答by Donny van V

This function is to check for a unique field. Arg 1: the array with selected data Arg 2: key to check Arg 3: value that must be "validated"

此功能用于检查唯一字段。Arg 1:具有选定数据的数组 Arg 2:检查的关键 Arg 3:必须“验证”的值

function objectUnique( array, field, value )
{
    var unique = true;
    array.forEach(function ( entry )
    {
        if ( entry[field] == value )
        {
            unique = false;
        }
    });

    return unique;
}