ChatGPT解决这个技术问题 Extra ChatGPT

确定数组是否包含值[重复]

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

我需要确定一个值是否存在于数组中。

我正在使用以下功能:

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

上面的函数总是返回 false。

数组值和函数调用如下:

arrValues = ["Sam","Great", "Sample", "High"]
alert(arrValues.contains("Sam"));
该代码适用于 Safari 4.0.2。顺便说一句:我会进行 === 比较,而不仅仅是 ==
“上面的函数总是返回 false。”不,它没有:该功能按预期工作 - 错误必须在其他地方。
Finally its worked. its due to improper trim of the comparing value. there was some space in the comparing value(提问者对 accepted answer 的评论。)
它有效,您应该使用 === 而不是 ==

C
Community

jQuery 有一个实用功能:

$.inArray(value, array)

返回 arrayvalue 的索引。如果 array 不包含 value,则返回 -1

另请参阅How do I check if an array includes an object in JavaScript?


不要让“inArray”这个名字欺骗了你。如上所述(当然我没有仔细阅读),如果元素不存在,则返回 -1(不是 false)。
@Steve Paul 名字有什么问题?它按照它所说的去做:-1=它不在那里,其他任何东西=它在那里
'inArray' 意味着将返回一个布尔值,指示是否可以在数组中找到该元素。因此,用户可能会想使用表达式: if ($.inArray('myval', myarray)) {...} 如果 'myval' 不在 myarray 中,这将评估为 true。此外,如果 myval 的索引为 0,它将评估为 false。
$.inArray 返回的非布尔值绝对感觉像是 jQuery 的一个错误。当然,它应该重命名为 $.indexOf,如果这是它的 polyfill 函数?
很容易建议某人对所有 javascript 都使用 JQuery 方法,但由于最初的问题是针对 javascript 解决方案,因此应该以这种方式提供
e
eyelidlessness
var contains = function(needle) {
    // Per spec, the way to identify NaN is that it is not equal to itself
    var findNaN = needle !== needle;
    var indexOf;

    if(!findNaN && typeof Array.prototype.indexOf === 'function') {
        indexOf = Array.prototype.indexOf;
    } else {
        indexOf = function(needle) {
            var i = -1, index = -1;

            for(i = 0; i < this.length; i++) {
                var item = this[i];

                if((findNaN && item !== item) || item === needle) {
                    index = i;
                    break;
                }
            }

            return index;
        };
    }

    return indexOf.call(this, needle) > -1;
};

你可以像这样使用它:

var myArray = [0,1,2],
    needle = 1,
    index = contains.call(myArray, needle); // true

CodePen validation/usage


注意,数组上的indexOf在IE中没有实现,但是可以自己定义
您应该使用与 === 的类型比较以与本机实现兼容
修复了比较并添加了缺失的 return -1;请注意,根据 ES5 规范,在有符号零和 NaN 的情况下,此方法的行为与本机方法不同(参见 15.4.4.14 和 9.12 与 11.9.6)
这个答案指的是哪个版本的IE?
请注意,在 Sharepoint 2010 中,如果您实现 Array.Prototype,WebParts 可能会中断:labs.steveottenad.com/type-mismatch-on-wpadder-js
C
Carlos

这通常是 indexOf() 方法的用途。你会说:

return arrValues.indexOf('Sam') > -1

indexOf 在 <IE9 中不起作用。
不适用于 NaN
我喜欢 Kenneth J 的评论如何获得比答案更多的支持。但是好东西 - 我已经将 indexOf() 用于字符串,但我不知道您通常可以将它用于数组。
如果数组中不存在元素,return ~arrValues.indexOf('Sam') 将返回 false
@SebastianMach,如果所有网络开发人员都表态说不......用户将被迫改变。并帮助公司节省资金,因为他们不必雇用 IE 开发人员
D
Dale

Array.prototype.includes()

在 ES2016 中,有 Array.prototype.includes()

includes() 方法确定数组是否包含某个元素,根据需要返回 true 或 false。

例子

["Sam", "Great", "Sample", "High"].includes("Sam"); // true

支持

根据 kangaxMDN,支持以下平台:

铬 47

边缘 14

火狐 43

歌剧 34

野生动物园 9

节点 6

可以使用 Babel(使用 babel-polyfill)或 core-js 扩展支持。 MDN 还提供了一个 polyfill

if (![].includes) {
  Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
    'use strict';
    var O = Object(this);
    var len = parseInt(O.length) || 0;
    if (len === 0) {
      return false;
    }
    var n = parseInt(arguments[1]) || 0;
    var k;
    if (n >= 0) {
      k = n;
    } else {
      k = len + n;
      if (k < 0) {k = 0;}
    }
    var currentElement;
    while (k < len) {
      currentElement = O[k];
      if (searchElement === currentElement ||
         (searchElement !== searchElement && currentElement !== currentElement)) {
        return true;
      }
      k++;
    }
    return false;
  };
}

我很想在几个关于多个变量值或数组的 javascript 问题中发布这个答案。 MDN 的 polyfill 很不错。
谢谢你! Babel polyfils 很好 :-) 我记得 2 年前 jQuery 在任何项目中,现在它是 Babel :) JavaScript 社区的巨大胜利!在包括 babel pollyfils 在内的许多平台上都有可用的 ES7 表格kangax.github.io/compat-table/es2016plus
R
Ryan McGeary

仅仅因为跨浏览器兼容性和效率的所有问题,使用像 lodash 这样的库几乎总是更安全。

效率,因为您可以保证在任何给定时间,像下划线这样非常流行的库将拥有完成这样的实用功能的最有效方法。

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

如果您担心通过包含整个库而添加到应用程序中的大量内容,请知道您可以单独包含功能:

var includes = require('lodash/collections/includes');

注意:对于旧版本的 lodash,这是 _.contains() 而不是 _.includes()


@threed,您不必包含整个库。部分功能可以包含在 require('lodash/collections/contains') 中。
仅供参考:使用 lodash 4 现在是 _.includes() 而不是 _.contains()
辅助库可能看起来很方便,但往往(太)改变,见上面的评论“lodash 4 '.contains()' is now '.includes()'”
@anneb 可以说任何图书馆。这就是为什么你有 semver 和依赖管理。
在 2.x 之前的 Lodash 版本中,_.include() 是 _.contains() 的别名,并且没有定义 _.includes()。从版本。 3.x、_.include() 和 _.contains() 都是 _includes() 的别名。但从版本。 4.x,只有 _.includes() 没有其他别名。
k
kuujinbo

从 ECMAScript6 开始,可以使用 Set

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

使用实际设置的好方法。
T
Trevor

tl;博士

function includes(k) {
  for(var i=0; i < this.length; i++){
    if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
      return true;
    }
  }
  return false;
}

例子

函数包括(k) { for(var i=0; i < this.length; i++){ if( this[i] === k || ( this[i] !== this[i] && k != = k ) ){ 返回真; } } 返回假; } function log(msg){ $('#out').append('

' + msg + '
'); } var arr = [1, "2", NaN, true]; arr.includes = 包括; log('var arr = [1, "2", NaN, true];');日志('
'); log('arr.includes(1): ' + arr.includes(1)); log('arr.includes(2): ' + arr.includes(2)); log('arr.includes("2"): ' + arr.includes("2")); log('arr.includes(NaN): ' + arr.includes(NaN)); log('arr.includes(true): ' + arr.includes(true)); log('arr.includes(false): ' + arr.includes(false)); #out{ 字体系列:等宽; }

更长的答案

我知道这个问题实际上并不是关于是否扩展内置对象,而是 OP 的尝试和对此答案的评论突出了这场辩论。我在 2013 年 2 月 12 日的评论引用了一篇很好地概述了这场辩论的文章,但是该链接断开了,我无法编辑原始评论,因为时间已经过去了,所以我将其包括在内 here

如果您希望使用 contains 方法扩展内置 Array 对象,那么最好和最负责任的方法可能是使用 MDN 中的这个 polyfill。 (另请参阅 MDN 关于原型继承的文章的 this 部分,其中解释了 “扩展内置原型的唯一充分理由是向后移植较新 JavaScript 引擎的功能;例如 Array.forEach 等.")

if (!Array.prototype.includes) {
  Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
    'use strict';
    var O = Object(this);
    var len = parseInt(O.length) || 0;
    if (len === 0) {
      return false;
    }
    var n = parseInt(arguments[1]) || 0;
    var k;
    if (n >= 0) {
      k = n;
    } else {
      k = len + n;
      if (k < 0) {k = 0;}
    }
    var currentElement;
    while (k < len) {
      currentElement = O[k];
      if (searchElement === currentElement ||
         (searchElement !== searchElement && currentElement !== currentElement)) {
        return true;
      }
      k++;
    }
    return false;
  };
}

不想要严格的平等,还是想要选择?

function includes(k, strict) {
  strict = strict !== false; // default is true
  // strict = !!strict; // default is false
  for(var i=0; i < this.length; i++){
    if( (this[i] === k && strict) || 
        (this[i] == k && !strict) ||
        (this[i] !== this[i] && k !== k)
    ) {
      return true;
    }
  }
  return false;
}

这种增加内置类型的技术不是很不受欢迎吗?
越野车:[1,2,4].contains([].contains) 是真的。由于相同的错误,也不必要地变慢。避免 for..in 超过数组。
@Eamon Nerbonne:我刚刚将该代码粘贴到 jsfiddle.net 并得到了错误。难道我做错了什么。另外,您能否详细说明此错误如何减慢代码速度?最后,我不知道“for..in”循环存在性能差异。您能否解释或指导我阅读可以阅读更多内容的文章?
@threed 完全不真实:“这是一种非常常见的做法,并且被 jQuery 广泛使用” - 他们为他们使用的某些对象创建新原型,但不修改内置原型
M
Matías Cánepa

我的小贡献:

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

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

S
SoEzPz

如果您有权访问 ECMA 5,则可以使用 some 方法。

MDN SOME Method Link

arrValues = ["Sam","Great", "Sample", "High"];

function namePresent(name){
  return name === this.toString();
}
// Note:
// namePresent requires .toString() method to coerce primitive value
// i.e. String {0: "S", 1: "a", 2: "m", length: 3, [[PrimitiveValue]]: "Sam"}
// into
// "Sam"

arrValues.some(namePresent, 'Sam');
=> true;

如果您有权访问 ECMA 6,则可以使用 include 方法。

MDN INCLUDES Method Link

arrValues = ["Sam","Great", "Sample", "High"];

arrValues.includes('Sam');
=> true;

r
rlovtang

给定 IE 的 indexOf 实现(如 eyelidlessness 所述):

Array.prototype.contains = function(obj) {
    return this.indexOf(obj) > -1;
};

那是多余的。
也许吧,但它让你的代码更干净。 if (myArray.contains(obj)) 比 if (myArray.indexOf(obj) > -1) 更容易阅读并更好地说明意图。我肯定会同时实施。
这适用于所有浏览器吗?或者某些浏览器是否认为“2”和 2 的索引相同?
W
Wojciech Bednarski

您可以使用 _.indexOf method,或者如果您不想在应用程序中包含整个 Underscore.js 库,您可以查看 how they did it 并提取必要的代码。

    _.indexOf = function(array, item, isSorted) {
    if (array == null) return -1;
    var i = 0, l = array.length;
    if (isSorted) {
      if (typeof isSorted == 'number') {
        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
      } else {
        i = _.sortedIndex(array, item);
        return array[i] === item ? i : -1;
      }
    }
    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
    for (; i < l; i++) if (array[i] === item) return i;
    return -1;
  };

H
Hunan Rostomyan

另一种选择是通过以下方式使用 Array.some (if available):

Array.prototype.contains = function(obj) {
  return this.some( function(e){ return e === obj } );
}

当且仅当数组中存在与 obj 相同的元素时,传递给 Array.some 的匿名函数才会返回 true。如果没有这样的元素,该函数将不会为数组的任何元素返回 true,因此 Array.some 也将返回 false


C
Chris Schmitz

哇,这个问题有很多很好的答案。

我没有看到采用 reduce 方法的方法,因此我将其添加到:

var searchForValue = 'pig';

var valueIsInArray = ['horse', 'cat', 'dog'].reduce(function(previous, current){
    return previous || searchForValue === current ? true : false;
}, false);

console.log('The value "' + searchForValue + '" is in the array: ' + valueIsInArray);

Here's a fiddle of it in action


我实际上正在考虑走这条路线,但即使找到结果,它仍然必须横穿整个数组。
@cgatian 这是一个好点。在选择使用哪种方法时要牢记这一点。您可以将 reduce 语句包装在 try catch 块中,并在找到值后抛出异常,但如果您这样做,我认为您会失去函数式方法为您提供的一些简单性。
K
Kakoroat

提供的答案对我不起作用,但它给了我一个想法:

Array.prototype.contains = function(obj)
    {
        return (this.join(',')).indexOf(obj) > -1;
    }

这并不完美,因为分组之外相同的项目最终可能会匹配。比如我的例子

var c=[];
var d=[];
function a()
{
    var e = '1';
    var f = '2';
    c[0] = ['1','1'];
    c[1] = ['2','2'];
    c[2] = ['3','3'];
    d[0] = [document.getElementById('g').value,document.getElementById('h').value];

    document.getElementById('i').value = c.join(',');
    document.getElementById('j').value = d.join(',');
    document.getElementById('b').value = c.contains(d);
}

当我使用分别包含 1 和 2 的 'g' 和 'h' 字段调用此函数时,它仍然找到它,因为连接的结果字符串是:1,1,2,2,3,3

由于在我的情况下我会遇到这种情况是值得怀疑的,所以我正在使用它。我想我会分享以防其他人也无法使选择的答案起作用。


这个解决方案似乎非常脆弱,除了最狭窄的情况外,在所有情况下都容易出错。例如,想象一下使用这个数组:var arr = ["Smith, Reed", "Jackson, Frank"]; arr.contains(searchTerm); 某个用户在搜索此数组的某个文本字段中意外键入 "Reed,Jackson" 而不是 "Reed, Jackson" 的图像。该算法将返回误报,用户会认为 Reed, Jackson 实际存在,但实际上它不存在。像这样的情况是这个算法更容易出现错误的原因。
N
Nikhil Vartak

使用对数组中的每个值执行函数的数组 .map 函数对我来说似乎是最干净的。

参考:Array.prototype.map()

此方法既适用于简单数组,也适用于需要查看对象数组中是否存在键/值的对象数组。

function inArray(myArray,myValue){
    var inArray = false;
    myArray.map(function(key){
        if (key === myValue){
            inArray=true;
        }
    });
    return inArray;
};

var anArray = [2,4,6,8]
console.log(inArray(anArray, 8)); // returns true
console.log(inArray(anArray, 1)); // returns false

function inArrayOfObjects(myArray,myValue,objElement){
    var inArray = false;
    myArray.map(function(arrayObj){
        if (arrayObj[objElement] === myValue) {
            inArray=true;
        }
    });
    return inArray;
};

var objArray = [{id:4,value:'foo'},{id:5,value:'bar'}]
console.log(inArrayOfObjects(objArray, 4, 'id')); // returns true
console.log(inArrayOfObjects(objArray, 'bar', 'value')); // returns true
console.log(inArrayOfObjects(objArray, 1, 'id')); // returns false

c
codefreaK
function setFound(){   
 var l = arr.length, textBox1 = document.getElementById("text1");
    for(var i=0; i<l;i++)
    {
     if(arr[i]==searchele){
      textBox1 .value = "Found";
      return;
     }
    }
    textBox1 .value = "Not Found";
return;
}

该程序检查是否找到给定的元素。 id text1 表示文本框的id,searchele 表示要搜索的元素(从用户那里获得);如果你想要索引,使用 i 值


请解释你的代码。仅代码答案不受欢迎
该程序检查是否找到给定的元素。 id text1 表示文本框的id,searchele 表示要搜索的元素(从用户那里获得);如果你想要索引,使用 i 值。
请在您的答案中更新它。
J
John Slegers

contains 函数的最简单解决方案是如下所示的函数:

var contains = function (haystack, needle) {
    return !!~haystack.indexOf(needle);
}

理想情况下,你不会让它成为一个独立的函数,而是一个帮助库的一部分:

var helper = {};

helper.array = {
    contains : function (haystack, needle) {
        return !!~haystack.indexOf(needle);
    }, 
    ...
};

现在,如果您碰巧是那些仍然需要支持 IE<9 并因此不能依赖 indexOf 的不幸者之一,您可以使用这个 polyfill,我得到了 from the MDN

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(searchElement, fromIndex) {
    var k;
    if (this == null) {
      throw new TypeError('"this" is null or not defined');
    }
    var o = Object(this);
    var len = o.length >>> 0;
    if (len === 0) {
      return -1;
    }
    var n = +fromIndex || 0;

    if (Math.abs(n) === Infinity) {
      n = 0;
    }
    if (n >= len) {
      return -1;
    }
    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
    while (k < len) {
      if (k in o && o[k] === searchElement) {
        return k;
      }
      k++;
    }
    return -1;
  };
}

v
valeri

我更喜欢简单:

var days = [1, 2, 3, 4, 5];
if ( 2 in days ) {console.log('weekday');}

他想在数组中找到一个值,而不是索引。因此,即使它很简单,这也无法完成工作。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…