如何检查数组是否在JavaScript中包含值?


3994

找出JavaScript数组是否包含值的最简洁,最有效的方法是什么?

这是我知道的唯一方法:

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

有没有更好,更简洁的方法来实现这一目标?

这与Stack Overflow问题密切相关。在JavaScript数组中查找项目的最佳方法?它解决了使用数组查找对象的问题indexOf


49
刚刚经过测试:您的方法实际上是跨浏览器最快的:jsperf.com/find-element-in-obj-vs-array/2(除了将a.length预先保存在变量中),同时使用indexOf(如$ .inArray)慢得多
JORN Berkefeld

17
许多人回答说Array#indexOf是您的​​最佳选择。但是,如果您希望将某些内容正确地转换为布尔值,请使用以下方法:~[1,2,3].indexOf(4)将返回0(其值为false),而~[1,2,3].indexOf(3)将返回-3(其值为true)。
lordvlad

8
~不是您想要用来转换为布尔值的对象!。但是在这种情况下,您要检查-1的相等性,因此该函数可能return [1,2,3].indexOf(3) === -1; ~不是二进制结尾,它将分别反转值的每一位。
mcfedr 2014年

14
@Iordvlad [1,2,3].indexOf(4)实际上将返回-1。正如@mcfedr所指出的那样,~它是按位表示NOT的运算符,请参见ES5 11.4.8。问题是,由于的二进制表示形式-1仅包含1,因此它的补码为0,其评估为false。其他任何数字的补数都将为非零,因此为true。因此,~效果很好,通常与结合使用indexOf
mknecht 2015年

5
标题具有误导性。在哪里[[1,2],[3,4]].includes([3,4])
mplungjan '17

Answers:


4373

现代的浏览器Array#includes,这不正是这一点,得到广泛支持的人,除IE:

console.log(['joe', 'jane', 'mary'].includes('jane')); //true

您还可以使用Array#indexOf,它不太直接,但是对于过时的浏览器不需要使用polyfill。


许多框架还提供类似的方法:

注意,有些框架将此功能实现为一个函数,而其他框架则将该函数添加到数组原型中。


42
MooTools还具有Array.contains,它返回一个布尔值,这听起来像是这里的真正问题。
瑞安·弗洛伦斯

22
原型还具有Array.include返回布尔值的功能
user102008 2010年

46
如果您使用的是优秀的浏览器,则可以使用array.indexOf(object) != -1
Sam Soffes 2010年

13
此外,不要使用单独的indexOf作为条件,因为第一个元素将返回0,并将作为falsy进行评估
加锁存

241
inArray是函数的糟糕名称,该函数返回元素的索引(-1如果不存在)。我希望会返回一个布尔值。
蒂姆(Tim)

433

从2019年开始更新:这个答案来自2008年(11岁!),与现代JS使用无关。承诺的性能改进基于当时在浏览器中完成的基准测试。它可能与现代JS执行上下文无关。如果您需要简单的解决方案,请寻找其他答案。如果您需要最佳性能,请在相关执行环境中为自己设定基准。

就像其他人说的那样,遍历数组可能是最好的方法,但是已经证明了,递减while循环是JavaScript中最快的迭代方法。因此,您可能希望按如下所示重写代码:

function contains(a, obj) {
    var i = a.length;
    while (i--) {
       if (a[i] === obj) {
           return true;
       }
    }
    return false;
}

当然,您也可以扩展Array原型:

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
}

现在,您可以简单地使用以下内容:

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false


22
“已证明”是一个有力的词。JS引擎不断改进,而3年前的执行时间已经过时了。
2011年

2
@Damir-我同意。也许将样本更改为使用indexOf(如果可用),以便人们盲目复制粘贴此代码将获得最佳性能。
2011年

1
@cbmeeks是的,绝对需要护理。一般情况下,for (o in array)遍历数组时可能不应该这样做……
DamirZekić2012年

1
最好的方法是检查[1,2,3] .indexOf(1)> -1
Devin G Rhode

206

indexOf 也许,但这是“ ECMA-262标准的JavaScript扩展;因此,该标准的其他实现中可能不存在此扩展”。

例:

[1, 2, 3].indexOf(1) => 0
["foo", "bar", "baz"].indexOf("bar") => 1
[1, 2, 3].indexOf(4) => -1

AFAICS 微软并没有提供某种替代的这一点,但你可以在Internet Explorer阵列(和不支持其他浏览器加入类似的功能indexOf,如果你希望),作为一个快速谷歌搜索发现(例如,这一个)。


实际上,在链接到的developer.mozilla.org页面上有一个不支持indexOf扩展的浏览器示例。
劳埃德·科腾

实际上,如果为不支持它的浏览器(即IE7)在Array原型中添加indexof,则它们在遍历数组中的项时也会尝试遍历此函数。讨厌。
CpILL


是否适用于检查Object?我不认为它工作在对象的情况下
Himesh Aadeshara

168

ECMAScript 7引入了Array.prototype.includes

可以这样使用:

[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false

它还接受一个可选的第二个参数fromIndex

[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true

不像indexOf,它采用严格相等比较includes比较了使用SameValueZero平等算法。这意味着您可以检测数组是否包含NaN

[1, 2, NaN].includes(NaN); // true

也不同于indexOfincludes不会跳过缺少的索引:

new Array(5).includes(undefined); // true

目前,它仍然是草稿,但可以对其进行多填充以使其在所有浏览器上均可使用。



1
同样相关的是,ES7兼容性表(看起来像chrome现在支持它)
样式

是否适用于检查Object?我不认为它工作在对象的情况下
Himesh Aadeshara

128

最佳答案采用的是原始类型,但是如果要确定数组是否包含具有某些特征的对象,则Array.prototype.some()是一个非常优雅的解决方案:

const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]

items.some(item => item.a === '3')  // returns true
items.some(item => item.a === '4')  // returns false

这样做的好处是,一旦找到元素,迭代就会中止,因此可以节省不必要的迭代周期。

此外,if由于它返回布尔值,因此它非常适合语句:

if (items.some(item => item.a === '3')) {
  // do something
}

*正如詹姆士(Jamess)在评论中指出的那样,在此答案发布之时,即2018年9月,Array.prototype.some()已得到完全支持:caniuse.com支持表


1
截至今天(2018年9月),完全支持Array.prototype.some():caniuse.com支持表
jamess

1
在适用于AWS Node.js Lambda的Node> = 8.10中工作,这很棒。非常干净和简单的解决方案!👍🏻–
约旦

1
@jamess可能受到很好的支持,但是请记住,Arrow functions在此示例中并没有很好的支持。欲了解更多详情请看这里:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
卡米尔WITKOWSKI

有短路吗?还是迭代整个数组(即使找到一个值)?
道格拉斯·

@DouglasGaskell一旦找到就中止了迭代(在答案中提到)
迈克尔

112

假设您已经定义了如下数组:

const array = [1, 2, 3, 4]

以下是检查其中是否有a的三种方法3。它们全部返回truefalse

本机数组方法(自ES2016起)(兼容性表

array.includes(3) // true

作为自定义数组方法(ES2016之前)

// Prefixing the method with '_' to avoid name clashes
Object.defineProperty(Array.prototype, '_includes', { value: function (v) { return this.indexOf(v) !== -1 }})
array._includes(3) // true

功能简单

const includes = (a, v) => a.indexOf(v) !== -1
includes(array, 3) // true

如果“ b”在数组“ a”中,则返回true ...我不知道还有其他解释方法……
william malo 2012年

4
这部分我不明白“ !!〜”。而且我认为这在IE8中将不起作用,因为IE8不支持Array对象上的indexOf()。
svlada 2012年

62
“〜”是对数字进行累加,求反和减去1的运算符。如果indexOf失败,则返回-1,因此“〜”将-1变成“ 0”。使用“!” 将数字变成布尔人(!! 0 === false)
威廉·马洛(William Malo

1
凉,但严重为了简化y的缘故不仅a.indexOf(B)> - 1,因为“> -1”。长度=== “!!〜”。长度
超级

2
我称缺乏对布尔运算符的影响的了解是不专业的。但是我同意可读代码的价值,我当然会将其包装在一个明确标记的函数中。这正是大多数主要的JS框架所做的事情。
okdewit '16

79

这是JavaScript 1.6兼容的实现Array.indexOf

if (!Array.indexOf) {
    Array.indexOf = [].indexOf ?
        function(arr, obj, from) {
            return arr.indexOf(obj, from);
        } :
        function(arr, obj, from) { // (for IE6)
            var l = arr.length,
                i = from ? parseInt((1 * from) + (from < 0 ? l : 0), 10) : 0;
            i = i < 0 ? 0 : i;
            for (; i < l; i++) {
                if (i in arr && arr[i] === obj) {
                    return i;
                }
            }
            return -1;
        };
}

这看起来不错,但有些困惑:*第1行和第3行的测试是否等效?*测试原型,并在必要时将函数添加到Array.prototype会更好吗?
Avi Flax 2010年

10
它们不是等价的。[].indexOf是的简写Array.prototype.indexOf。美国偏执狂的Javascript程序员避免不惜一切代价扩展本机原型。
三月Örlygsson

1
是否不[].indexOf创建新数组然后访问indexOf,而Array.prototype.indexOf直接访问原型?
Alex

3
@alex是[].indexOf === Array.prototype.indexOf(在FireBug中尝试一下),但是相反[].indexOf !== Array.indexOf
三月Örlygsson

57

采用:

function isInArray(array, search)
{
    return array.indexOf(search) >= 0;
}

// Usage
if(isInArray(my_array, "my_value"))
{
    //...
}

25
x ? true : false通常是多余的。是这里。
Ry-

@minitech为什么您说这是多余的?
马蒂亚斯·卡内帕

8
array.indexOf(search) >= 0已经是布尔值。只是return array.indexOf(search) >= 0
Ry-

@minitech很好,谢谢!实际上,我不知道这样的构造是否可以归还。直到有新东西。
马蒂亚斯·卡内帕

从字面上看,可以返回javascript中的任何构造
BT

49

扩展JavaScript Array对象是一个很糟糕的主意,因为您将新属性(您的自定义方法)引入了for-in可能破坏现有脚本的循环中。几年前,原型库的作者不得不重新设计其库实现,以删除此类内容。

如果您不必担心与页面上运行的其他JavaScript的兼容性,请坚持下去,否则,我建议您使用更笨拙但更安全的独立功能解决方案。


22
我不同意。正是由于这个原因,For-in循环不应用于数组。使用流行的js库之一时,使用for-in循环会中断
Tomas

这会被视为猴子修补吗?大声笑有些人喜欢那样。
cbmeeks 2012年

33

单线:

function contains(arr, x) {
    return arr.filter(function(elem) { return elem == x }).length > 0;
}

8
array.filter(e=>e==x).length > 0等效array.some(e=>e==x)some更有效
Apolo




19

希望更快的双向indexOf/ lastIndexOf替代

2015年

尽管新方法包括的非常好,但目前支持基本上为零。

很长一段时间以来,我一直在考虑替换慢速indexOf / lastIndexOf函数的方法。

已经找到了一种表现最佳的方法,寻找最重要的答案。从这些中,我选择了contains@Damir Zekic发布的功能,该功能应该是最快的。但是它也指出基准是从2008年开始的,因此已经过时了。

我也喜欢whilefor,但不具体原因我结束了编写函数for循环。也可以用while --

我很好奇,如果在执行过程中检查数组的两侧,迭代是否会慢得多。显然没有,因此此功能比最受好评的功能快大约两倍。显然,它也比本地的要快。在现实环境中,您永远都不知道要搜索的值是在数组的开头还是结尾。

当您知道只是使用一个值推入一个数组时,使用lastIndexOf可能仍然是最好的解决方案,但是如果必须遍历大数组并且结果可能无处不在,那么这可能是使事情变得更快的可靠解决方案。

双向indexOf / lastIndexOf

function bidirectionalIndexOf(a, b, c, d, e){
  for(c=a.length,d=c*1; c--; ){
    if(a[c]==b) return c; //or this[c]===b
    if(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
  }
  return -1
}

//Usage
bidirectionalIndexOf(array,'value');

性能测试

http://jsperf.com/bidirectionalindexof

作为测试,我创建了一个包含100k条目的数组。

三个查询:数组的开头,中间和结尾。

我希望您也觉得这很有趣并测试性能。

注意:如您所见,我对contains函数进行了一些修改,以反映indexOf和lastIndexOf的输出(因此基本上trueindexfalse一起使用-1)。那不应该伤害它。

数组原型变体

Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){
  for(c=this.length,d=c*1; c--; ){
    if(this[c]==b) return c; //or this[c]===b
    if(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
  }
  return -1
},writable:false, enumerable:false});

// Usage
array.bidirectionalIndexOf('value');

还可以轻松修改该函数以返回true或false,甚至返回对象,字符串或其他内容。

这是while变体:

function bidirectionalIndexOf(a, b, c, d){
  c=a.length; d=c-1;
  while(c--){
    if(b===a[c]) return c;
    if(b===a[d-c]) return d-c;
  }
  return c
}

// Usage
bidirectionalIndexOf(array,'value');

这怎么可能?

我认为,获取数组中反映索引的简单计算是如此简单,以至于它比实际循环迭代快两倍。

这是一个复杂的示例,每个迭代执行三个检查,但是这只有在较长的计算时才有可能,这会导致代码变慢。

http://jsperf.com/bidirectionalindexof/2


18

性能

今天2020.01.07,我在15种解决方案的Chrome v78.0.0,Safari v13.0.4和Firefox v71.0.0的MacOs HighSierra 10.13.6上进行了测试。结论

  • 令人惊讶的是JSON,基于的解决方案(K,N,O)在所有浏览器中速度最快Setfind
  • es6 includes(F)仅在chrome上快速
  • 基于for(C,D)和indexOf(G,H)大小数组上的所有浏览器上都非常快,因此它们可能是高效解决方案的最佳选择
  • 循环期间索引减少的解决方案(B)较慢,可能是因为CPU缓存的工作方式
  • 当搜索到的元素位于数组长度的66%时,我还对大型数组进行了测试,基于for(C,D,E)的解决方案给出了相似的结果(〜630 ops / sec-但是Safari和Firefox中的E为10-比C和D慢20%)

结果

在此处输入图片说明

细节

我执行2个测试用例:包含10个元素的数组和包含1百万个元素的数组。在这两种情况下,我们都将搜索到的元素放在数组中间。

小数组-10个元素

您可以在此处执行测试

在此处输入图片说明

大数组-1.000.000元素

您可以在此处执行测试

在此处输入图片说明



16
function inArray(elem,array)
{
    var len = array.length;
    for(var i = 0 ; i < len;i++)
    {
        if(array[i] == elem){return i;}
    }
    return -1;
} 

如果找到,则返回数组索引;如果未找到,则返回-1


16

我们使用以下代码段(适用于对象,数组,字符串):

/*
 * @function
 * @name Object.prototype.inArray
 * @description Extend Object prototype within inArray function
 *
 * @param {mix}    needle       - Search-able needle
 * @param {bool}   searchInKey  - Search needle in keys?
 *
 */
Object.defineProperty(Object.prototype, 'inArray',{
    value: function(needle, searchInKey){

        var object = this;

        if( Object.prototype.toString.call(needle) === '[object Object]' || 
            Object.prototype.toString.call(needle) === '[object Array]'){
            needle = JSON.stringify(needle);
        }

        return Object.keys(object).some(function(key){

            var value = object[key];

            if( Object.prototype.toString.call(value) === '[object Object]' || 
                Object.prototype.toString.call(value) === '[object Array]'){
                value = JSON.stringify(value);
            }

            if(searchInKey){
                if(value === needle || key === needle){
                return true;
                }
            }else{
                if(value === needle){
                    return true;
                }
            }
        });
    },
    writable: true,
    configurable: true,
    enumerable: false
});

用法:

var a = {one: "first", two: "second", foo: {three: "third"}};
a.inArray("first");          //true
a.inArray("foo");            //false
a.inArray("foo", true);      //true - search by keys
a.inArray({three: "third"}); //true

var b = ["one", "two", "three", "four", {foo: 'val'}];
b.inArray("one");         //true
b.inArray('foo');         //false
b.inArray({foo: 'val'})   //true
b.inArray("{foo: 'val'}") //false

var c = "String";
c.inArray("S");        //true
c.inArray("s");        //false
c.inArray("2", true);  //true
c.inArray("20", true); //false

15

如果您要反复检查数组中是否存在对象,则应该检查一下

  1. 通过在数组中进行插入排序(始终将新对象放在正确的位置)来始终保持数组的排序
  2. 使更新对象成为remove + sorted插入操作,并且
  3. 在中使用二进制搜索查找contains(a, obj)

2
或者,如果可能的话,请完全停止使用数组,而应将对象用作字典,如MattMcKnight和ninjagecko所建议的那样。
joeytwiddle

13

适用于所有现代浏览器的解决方案:

function contains(arr, obj) {
  const stringifiedObj = JSON.stringify(obj); // Cache our object to not call `JSON.stringify` on every iteration
  return arr.some(item => JSON.stringify(item) === stringifiedObj);
}

用法:

contains([{a: 1}, {a: 2}], {a: 1}); // true

IE6 +解决方案:

function contains(arr, obj) {
  var stringifiedObj = JSON.stringify(obj)
  return arr.some(function (item) {
    return JSON.stringify(item) === stringifiedObj;
  });
}

// .some polyfill, not needed for IE9+
if (!('some' in Array.prototype)) {
  Array.prototype.some = function (tester, that /*opt*/) {
    for (var i = 0, n = this.length; i < n; i++) {
      if (i in this && tester.call(that, this[i], i, this)) return true;
    } return false;
  };
}

用法:

contains([{a: 1}, {a: 2}], {a: 1}); // true

为什么要使用JSON.stringify

Array.indexOfArray.includes(以及此处的大多数答案)仅按参考进行比较,而不按值进行比较。

[{a: 1}, {a: 2}].includes({a: 1});
// false, because {a: 1} is a new object

奖金

未优化的ES6单缸纸:

[{a: 1}, {a: 2}].some(item => JSON.stringify(item) === JSON.stringify({a: 1));
// true

注意:如果键的顺序相同,则按值比较对象会更好,因此,为了安全起见,您可以首先使用以下程序包对键进行排序:https : //www.npmjs.com/package/sort-keys


contains通过性能优化更新了该功能。感谢itinance指出。


此特定代码块可能在IE6中工作(未经测试),但是IE直到IE9才支持ES5。
马克·里德

出于性能方面的考虑,您应该避免字符串化。至少您应该避免在每个循环上使用JSON.stringify“ obj”,因为它很昂贵,并且会降低应用程序的速度。因此,您应该在温度变量的for循环之前捕获它
itinance

1
@itinance好点。includes根据您的建议更新了功能。我已经用我的函数运行了jsperf。它比lodash的速度慢大约5倍。尽管lodash无法按值进行比较,也无法{a: 1}在中找到[{a: 1}]。我不知道是否有图书馆这样做。但是我很好奇是否还有更多的表现方式,并且没有疯狂的复杂方式。
伊戈尔·巴巴辛

后期注意:这不适用于例如contains([{ a: 1, b: 2 }], { b: 2, a: 1 })字符串化的对象保持属性顺序的情况。
Heretic Monkey”,

1
@HereticMonkey,是的。这就是为什么我添加的sort-keys音符在底部
伊戈尔Barbashin

12

使用lodash的一些功能。

它简洁,准确,并且具有强大的跨平台支持。

接受的答案甚至不符合要求。

要求:推荐一种最简洁,最有效的方法来找出JavaScript数组是否包含对象。

接受的答案:

$.inArray({'b': 2}, [{'a': 1}, {'b': 2}])
> -1

我的建议:

_.some([{'a': 1}, {'b': 2}], {'b': 2})
> true

笔记:

$ .inArray可以很好地确定标量数组中是否存在量值...

$.inArray(2, [1,2])
> 1

...但是这个问题显然要求一种有效的方法来确定对象是否包含在数组中。

为了同时处理标量和对象,可以执行以下操作:

(_.isObject(item)) ? _.some(ary, item) : (_.indexOf(ary, item) > -1)

10

ECMAScript 6有很好的建议。

find方法对数组中存在的每个元素执行一次回调函数,直到找到其中回调返回真值的元素为止。如果找到这样的元素,则find立即返回该元素的值。否则,find返回未定义的。仅对具有指定值的数组索引调用回调;对于已删除或从未分配值的索引,不会调用它。

这是MDN文档

查找功能的工作原理如下。

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

您可以通过定义功能在ECMAScript 5及更低版本中使用此功能

if (!Array.prototype.find) {
  Object.defineProperty(Array.prototype, 'find', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(predicate) {
      if (this == null) {
        throw new TypeError('Array.prototype.find called on null or undefined');
      }
      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }
      var list = Object(this);
      var length = list.length >>> 0;
      var thisArg = arguments[1];
      var value;

      for (var i = 0; i < length; i++) {
        if (i in list) {
          value = list[i];
          if (predicate.call(thisArg, value, i, list)) {
            return value;
          }
        }
      }
      return undefined;
    }
  });
}


9

尽管这array.indexOf(x)!=-1是最简洁的方法(并且十多年来一直受非Internet Explorer浏览器的支持...),但这不是O(1),而是O(N),这很糟糕。如果您的数组不会改变,则可以将其转换为哈希表,然后执行table[x]!==undefined以下操作===undefined

Array.prototype.toTable = function() {
    var t = {};
    this.forEach(function(x){t[x]=true});
    return t;
}

演示:

var toRemove = [2,4].toTable();
[1,2,3,4,5].filter(function(x){return toRemove[x]===undefined})

(不幸的是,虽然您可以创建一个Array.prototype.contains来“冻结”一个数组并将哈希表存储在两行中的this._cache中,但是如果您以后选择编辑数组,则会产生错误的结果。JavaScript的钩子不足让您保持这种状态,例如与Python不同。)


9

可以使用具有方法“ has()”的Set

function contains(arr, obj) {
      var proxy = new Set(arr);
      if (proxy.has(obj))
        return true;
      else
        return false;
    }

    var arr = ['Happy', 'New', 'Year'];
    console.log(contains(arr, 'Happy'));


5
我认为return proxy.has(obj)这比使用if-else语句的两行要干净得多
Maciej Bukowski

function contains(arr, obj) { return new Set(arr).has(obj); }
Gordon Bean

8

采用:

var myArray = ['yellow', 'orange', 'red'] ;

alert(!!~myArray.indexOf('red')); //true

演示版

要确切地知道 tilde ~操作,请参考以下问题:代字号在表达式之前会做什么?


5
这已经在一年半前发布了无需重复。
暗影巫师为您耳边

3
实际上,它尚未发布。不是作为答案,而是作为对答案的评论,即使如此,它也不是很清楚和简洁。感谢您发布它,Mina Gabriel。
T.CK

6

好的,您只需优化代码即可获得结果!

有很多方法可以做到这一点越来越好,但是我只是想获取您的模式并将其应用到,JSON.stringify只需在您的情况下简单地执行以下操作即可:

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (JSON.stringify(a[i]) === JSON.stringify(obj)) {
            return true;
        }
    }
    return false;
}

后期注意:这不适用于例如contains([{ a: 1, b: 2 }], { b: 2, a: 1 })字符串化的对象保持属性顺序的情况。
异端猴子

5

绝不是最好的,但我只是在发挥创造力并增加曲目。

不要使用这个

Object.defineProperty(Array.prototype, 'exists', {
  value: function(element, index) {

    var index = index || 0

    return index === this.length ? -1 : this[index] === element ? index : this.exists(element, ++index)
  }
})


// Outputs 1
console.log(['one', 'two'].exists('two'));

// Outputs -1
console.log(['one', 'two'].exists('three'));

console.log(['one', 'two', 'three', 'four'].exists('four'));


如果不是这样,您应该使用什么?
bryc

@bryc可能是接受的解决方案,或者是这里的其他解决方案。如果您不太在意性能,那么可以使用此功能
sqram

5

奇怪的是,这个问题仍然没有添加最新的语法,使我增加了2美分。

假设我们有Objects arrObj数组,我们想在其中搜索obj。

Array.prototype。indexOf ->(返回index或-1)通常用于查找数组中元素的索引。这也可以用于搜索对象,但是仅当您将引用传递给同一对象时才有效。

let obj = { name: 'Sumer', age: 36 };
let arrObj = [obj, { name: 'Kishor', age: 46 }, { name: 'Rupen', age: 26 }];


console.log(arrObj.indexOf(obj));// 0
console.log(arrObj.indexOf({ name: 'Sumer', age: 36 })); //-1

console.log([1, 3, 5, 2].indexOf(2)); //3

Array.prototype。包括 ->(返回truefalse

console.log(arrObj.includes(obj));  //true
console.log(arrObj.includes({ name: 'Sumer', age: 36 })); //false

console.log([1, 3, 5, 2].includes(2)); //true

Array.prototype。find ->(进行回调,返回在CB中返回true的第一个值/对象)。

console.log(arrObj.find(e => e.age > 40));  //{ name: 'Kishor', age: 46 }
console.log(arrObj.find(e => e.age > 40)); //{ name: 'Kishor', age: 46 }

console.log([1, 3, 5, 2].find(e => e > 2)); //3

Array.prototype。findIndex ->(进行回调,返回在CB中返回true的第一个值/对象的索引)。

console.log(arrObj.findIndex(e => e.age > 40));  //1
console.log(arrObj.findIndex(e => e.age > 40)); //1

console.log([1, 3, 5, 2].findIndex(e => e > 2)); //1

由于find和findIndex需要回调,因此可以通过创造性地设置true条件来从数组中获取任何对象(即使没有引用)。


5

对此要求的简单解决方案是使用 find()

如果您有如下所示的对象数组,

var users = [{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "admin"},
{id: "105", name: "user"}];

然后,您可以检查具有您的值的对象是否已经存在

let data = users.find(object => object['id'] === '104');

如果data为null,则没有admin,否则它将返回现有对象,如下所示。

{id: "104", name: "admin"}

然后,您可以在数组中找到该对象的索引,并使用以下代码替换该对象。

let indexToUpdate = users.indexOf(data);
let newObject = {id: "104", name: "customer"};
users[indexToUpdate] = newObject;//your new object
console.log(users);

您将获得如下所示的价值

[{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "customer"},
{id: "105", name: "user"}];

希望这会对任何人有帮助。


5

    function countArray(originalArray) {
     
    	var compressed = [];
    	// make a copy of the input array
    	var copyArray = originalArray.slice(0);
     
    	// first loop goes over every element
    	for (var i = 0; i < originalArray.length; i++) {
     
    		var count = 0;	
    		// loop over every element in the copy and see if it's the same
    		for (var w = 0; w < copyArray.length; w++) {
    			if (originalArray[i] == copyArray[w]) {
    				// increase amount of times duplicate is found
    				count++;
    				// sets item to undefined
    				delete copyArray[w];
    			}
    		}
     
    		if (count > 0) {
    			var a = new Object();
    			a.value = originalArray[i];
    			a.count = count;
    			compressed.push(a);
    		}
    	}
     
    	return compressed;
    };
    
    // It should go something like this:
    
    var testArray = new Array("dog", "dog", "cat", "buffalo", "wolf", "cat", "tiger", "cat");
    var newArray = countArray(testArray);
    console.log(newArray);

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.