ChatGPT解决这个技术问题 Extra ChatGPT

检查数组中是否存在元素[重复]

这个问题在这里已经有了答案:How do I check if an array contains a value in JavaScript? (57 个回答) 5 年前关闭。

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

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

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

在我看来很好。当然,如果您的数组已排序,则可以改为进行二进制搜索。或者,如果数组中的每个值始终是唯一的,您可以改用基于地图的方法。
== 运算符?你真的想明确地允许类型强制吗?当然不是。因此,请改用 === 运算符。
在循环之前声明 count 是明智的。您也可以只用 for(var i=haystack.length; i--;) 替换这两行
对于数字,也可以使用 in 运算符(例如 (5 in array)。它可能比其他选项更快,但不适用于字符串或对象或任何其他非数字。

A
Alister

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 月,此has been implemented在几乎所有主要浏览器中,如果您需要支持旧版浏览器,polyfill 可用。

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


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

代码:

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

执行:

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

更新(2017 年):

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

常量数组 = [1, 2, 3];常量值 = 1; const isInArray = array.includes(value);控制台.log(isInArray); // 真的


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

只需使用 indexOf

haystack.indexOf(needle) >= 0

如果您想支持旧的 Internet Explorer (< IE9),您必须include your current code as a workaround though

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


Array.prototype.indexOf 未在 IE8 中实现。
在 IE 中不支持(可能仅在 9 中)stackoverflow.com/questions/1744310/…
这在页面上注明,但作为答案的一部分值得一提:indexOf 是 JavaScript 的一个相对较新的添加,在 9.0 之前的 IE 版本中不受支持。还值得注意的是,indexOf 仍然是 O(n),所以如果 OP 在速度/性能方面意味着“更好”,这实际上不会更好,只是更短。
@Tomalak Geret'kal 是的,尽管争论很简单。添加了一个关于性能的段落,以防性能是 OP 对 better 的含义。
@Francisc - 然后您可以尝试基于地图的方法。那么您的 inArray() 实现可以像 return haystack[needle] != undefined; 一样简单。
p
psyduck.the.apex.predator

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

~ 1500 ms,包括(当我使用 polyfill 时 ~ 2700 ms)

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 毫秒,indexOf

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
A
Akarsh Satija

单行代码.. 将返回 true 或 false

!!(arr.indexOf("val")+1)

bc 每个人都喜欢波浪号 !!~arr.indexOf("val")
或仅使用 ~arr.indexOf("val")。 0 = 虚假,其他数字 = 真实
呃,0应该是真的,因为它是数组中的第一个元素?
如果您必须迎合 IE11,则最好的解决方案。
E
Eem Jee

您可以使用 indexOf,但在 Internet Explorer 的最新版本中无法正常工作。 代码:

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

执行:

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

我建议您使用以下代码:

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

N
Nicolas

从 ECMAScript6 开始,可以使用 Set :

var myArray = ['A', 'B', 'C'];
var mySet = new Set(myArray);
var hasB = mySet.has('B'); // true
var hasZ = mySet.has('Z'); // false

C
Chris Alley

您可以使用 underscore.js 库中的 _contains 函数来实现此目的:

if (_.contains(haystack, needle)) {
  console.log("Needle found.");
};

下划线库只是为了这个?
不一定,因为开发人员可能已经在他们的应用程序中使用 Underscore 来实现其他功能。使用下划线是众多解决方案中的一种。
C
Connor Leech

在 lodash 中,您可以使用 _.includes(它也是 _.contains 的别名)

您可以搜索整个数组:

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

您可以从起始索引搜索数组:

_.includes([1, 2, 3], 1, 1);  // false (begins search at index 1)

搜索字符串:

_.includes('pebbles', 'eb');  // true (string contains eb)

也适用于检查简单的对象数组:

_.includes({ 'user': 'fred', 'age': 40 }, 'fred');    // true
_.includes({ 'user': 'fred', 'age': false }, false);  // true

关于最后一种情况需要注意的一点是,它适用于字符串、数字和布尔值等原语,但不能搜索数组或对象

_.includes({ 'user': 'fred', 'age': {} }, {});   // false
_.includes({ 'user': [1,2,3], 'age': {} }, 3);   // false