确定一个数组是否包含一个值
我需要确定一个数组中是否存在一个值。
我正在使用以下function:
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"));
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
CodePenvalidation/使用
jQuery有一个实用的function:
$.inArray(value, array)
返回array
的value
索引。 如果array
不包含value
则返回-1
。
另请参见如何检查数组是否包含JavaScript中的对象?
这通常是indexOf()方法的用途。 你会说:
return arrValues.indexOf('Sam') > -1
Array.prototype.includes()
在ES2016中,有Array.prototype.includes()
。
includes()
方法确定数组是否包含某个元素,并根据需要返回true
或false
。
例
["Sam", "Great", "Sample", "High"].includes("Sam"); // true
支持
根据kangax和MDN ,支持以下平台:
- Chrome 47
- 边缘14
- Firefox 43
- 歌剧34
- Safari 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; }; }
仅仅因为所有跨浏览器兼容性和效率的问题,使用像lodash这样的库几乎总是比较安全的。
效率,因为你可以保证,在任何时候,像下划线这样一个非常受欢迎的库将有最有效的方法来完成这样的效用函数。
_.includes([1, 2, 3], 3); // returns true
如果您担心包含整个库的应用程序被添加到应用程序中,请确保您可以单独包含function:
var includes = require('lodash/collections/includes');
注意:使用老版本的lodash,这是_.contains()
而不是_.includes()
。
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; }
例
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; } function log(msg){ $('#out').append('<div>' + msg + '</div>'); } var arr = [1, "2", NaN, true]; arr.includes = includes; log('var arr = [1, "2", NaN, true];'); log('<br/>'); 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{ font-family:monospace; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id=out></div>
由于ECMAScript6,可以使用Set
:
var myArray = ['A', 'B', 'C']; var mySet = new Set(myArray); var hasB = mySet.has('B'); // true var hasZ = mySet.has('Z'); // false
鉴于IE的indexOf的实现(如眼皮所述):
Array.prototype.contains = function(obj) { return this.indexOf(obj) > -1; };
我的小小贡献:
function isInArray(array, search) { return array.indexOf(search) >= 0; } //usage if(isInArray(my_array, "my_value")) { //... }
你可以使用_.indexOf方法,或者如果你不想在应用中包含整个Underscore.js库,你可以看看他们是如何做到的,并提取必要的代码。
_.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; };
如果您有权访问ECMA 5,则可以使用某种方法。
MDN某些方法链接
arrValues = ["Sam","Great", "Sample", "High"]; function namePresent(name){ return name === this.toString(); } // Note: // namePresent requires .toString() method to coerce primitive value // ie String {0: "S", 1: "a", 2: "m", length: 3, [[PrimitiveValue]]: "Sam"} // into // "Sam" arrValues.some(namePresent, 'Sam'); => true;
如果您有权访问ECMA 6,则可以使用includes方法。
MDN包括Method Link
arrValues = ["Sam","Great", "Sample", "High"]; arrValues.includes('Sam'); => true;
另一种select是以如下方式使用Array.some
( 如果可用 ):
Array.prototype.contains = function(obj) { return this.some( function(e){ return e === obj } ); }
传递给Array.some
的匿名函数将返回true
当且仅当数组中有一个与obj
相同的元素时。 缺less这样的元素,函数不会返回数组中的任何元素,所以Array.some
也会返回false
。
哇,这个问题有很多很好的答案。
我没有看到一个采取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);
这是它的一个小提琴在行动 。
提供的答案不适合我,但它给了我一个想法:
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'字段调用这个函数时,它仍然会find它,因为从连接产生的string是:1,1,2,2,3,3
由于我在这种情况下会遇到这样的情况,所以我正在使用这个。 我以为我会分享别人无法做出select的答案工作。
使用array .map函数为数组中的每个值执行一个函数似乎对我来说是最清洁的。
Ref: 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
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; }
这个程序检查给定的元素是否被find。 id text1表示文本框的id,searchele表示要被search的元素(从前用户); 如果你想索引,使用我的价值
contains
函数的最简单的解决scheme将是一个如下所示的函数:
var contains = function (haystack, needle) { return !!~haystack.indexOf(needle); }
理想情况下,你不会把它作为一个独立的函数,而是一个辅助函数库的一部分:
var helper = {}; helper.array = { contains : function (haystack, needle) { return !!~haystack.indexOf(needle); }, ... };
现在,如果你碰巧是那些不幸的人仍然需要支持IE <9,因此不能依靠indexOf
,你可以使用这个从MDN得到的polyfill :
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; }; }
我更喜欢简单:
var days = [1, 2, 3, 4, 5]; if ( 2 in days ) {console.log('weekday');}