检查数组中是否存在元素

IT技术 javascript arrays
2021-01-11 08:56:32

我现在用来检查的功能如下:

function inArray(needle,haystack)
{
    var count=haystack.length;
    for(var i=0;i<count;i++)
    {
        if(haystack[i]===needle){return true;}
    }
    return false;
}

有用。我正在寻找的是是否有更好的方法来做到这一点。

6个回答

ECMAScript 2016包含了includes()一种专门解决该问题的数组方法,因此现在是首选方法。

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(1, 2);  // false (second parameter is the index position in this array at which to begin searching)

截至 2018 年 7 月,这在几乎所有主要浏览器中实现,如果您需要支持旧浏览器,则可以使用polyfill

编辑:请注意,如果数组中的项目是对象,则返回 false。这是因为相似的对象在 JavaScript 中是两个不同的对象。

什么是polyfill?
2021-03-14 08:56:32
@nirvanaswap polyfill 是一个脚本,您可以使用它来确保任何浏览器都将实现您正在使用的某些东西。在这种情况下,您将添加一个脚本来检查if ("includes" in Array.prototype),如果没有,则实现它(例如,使用像Benny's answer这样的解决方案)。MDN文档(也链接到这个答案)实际上提供了一个给你。
2021-03-14 08:56:32
我像下面这样使用它,并且工作正常。并且不要推送重复值。非常感谢!!this.state.UpdatedfriendList.includes(s.valueKey)===false?this.state.UpdatedfriendList.push(s.valueKey):'';
2021-03-15 08:56:32
使用广泛支持myArray.indexOf(myVal) > -1是同一件事,但更安全
2021-03-23 08:56:32
@PrithiviRaj 这将是线性时间,因此性能影响将与数组的大小成正比。
2021-03-28 08:56:32

代码:

function isInArray(value, array) {
  return array.indexOf(value) > -1;
}

执行:

isInArray(1, [1,2,3]); // true

更新(2017):

在遵循 ECMAScript 2016 (ES7) 标准的现代浏览器中,您可以使用函数Array.prototype.includes,这可以更轻松地检查数组中是否存在项目:

const array = [1, 2, 3];
const value = 1;
const isInArray = array.includes(value);
console.log(isInArray); // true

在节点 4.4.7 中工作
2021-03-16 08:56:32
据我所知,ES2016(包括数组的 includes 方法)是 ECMAScript 的第七版。6. 版本是 ES 2015,不包含“包含”。请纠正。en.wikipedia.org/wiki/ECMAScript#7th_Edition_-_ECMAScript_2016
2021-03-18 08:56:32
!==-1 [额外字符]
2021-03-31 08:56:32
@totaldesign工作不仔细,你的意思是它在 IE 中工作不小心吗?:D
2021-04-06 08:56:32
indexOf 在 IE 浏览器中不小心工作。
2021-04-10 08:56:32

只需使用indexOf

haystack.indexOf(needle) >= 0

如果您想支持旧的 Internet Explorer (< IE9),则必须包含您当前的代码作为解决方法

除非您的列表已排序,否则您需要将每个值与指针进行比较。因此,您的解决方案和indexOf都必须执行n/2平均比较。然而,由于它indexOf是一个内置方法,它可能会使用额外的优化,并且在实践中会稍微快一点。请注意,除非您的应用程序在列表中搜索非常频繁(例如每秒 1000 次)或列表很大(例如 100k 个条目),否则速度差异无关紧要。

这在页面上已注明,但作为答案的一部分值得一提: indexOf是 JavaScript 的一个相对较新的补充,在 9.0 之前的 IE 版本中不受支持。同样值得注意的是,它indexOf仍然是 O(n),所以如果 OP 在速度/性能方面意味着“更好”,那么这不会真的更好,只是更短。
2021-03-13 08:56:32
@Francisc - 那么你可以尝试一种基于地图的方法。那么您的inArray()实现就可以像return haystack[needle] != undefined;.
2021-03-19 08:56:32
IE 不支持(可能只有 9 个)stackoverflow.com/questions/1744310/...
2021-03-25 08:56:32
Array.prototype.indexOf 未在 IE8 中实现。
2021-03-28 08:56:32
@Tomalak Geret'kal 没错,虽然这个论点很简单。添加了一段关于性能的内容,以防万一性能是 OP 对better.
2021-04-09 08:56:32

我在 Google Chrome 52 上对其进行了多次基准测试,但可以随意将其复制粘贴到任何其他浏览器的控制台中。


~ 1500 毫秒,包括(当我使用polyfill时 ~ 2700 毫秒

var array = [0,1,2,3,4,5,6,7,8,9]; 
var result = 0;

var start = new Date().getTime();
for(var i = 0; i < 10000000; i++)
{
  if(array.includes("test") === true){ result++; }
}
console.log(new Date().getTime() - start);

~ 1050 毫秒,索引

var array = [0,1,2,3,4,5,6,7,8,9]; 
var result = 0;

var start = new Date().getTime();
for(var i = 0; i < 10000000; i++)
{
  if(array.indexOf("test") > -1){ result++; }
}
console.log(new Date().getTime() - start);

~ 650 ms,自定义功能

function inArray(target, array)
{

/* Caching array.length doesn't increase the performance of the for loop on V8 (and probably on most of other major engines) */

  for(var i = 0; i < array.length; i++) 
  {
    if(array[i] === target)
    {
      return true;
    }
  }

  return false; 
}

var array = [0,1,2,3,4,5,6,7,8,9]; 
var result = 0;

var start = new Date().getTime();
for(var i = 0; i < 10000000; i++)
{
  if(inArray("test", array) === true){ result++; }
}
console.log(new Date().getTime() - start);
~ 950 / 750 / 650 在我的笔记本电脑上。我刚刚将数组更改为 ['df','ff',2,3,4,5,6,333,8,9] 并得到 ~ 950 / 900 / 3150
2021-04-05 08:56:32

单行代码.. 将返回真或假

!!(arr.indexOf("val")+1)
或者只是使用~arr.indexOf("val"). 0 = 假,其他数字 = 真
2021-03-30 08:56:32
bc 每个人都喜欢波浪号 !!~arr.indexOf("val")
2021-04-01 08:56:32
呃,0 应该是真的,因为它被发现是数组中的第一个元素?
2021-04-03 08:56:32
如果您必须迎合 IE11,则是最佳解决方案。
2021-04-07 08:56:32