簡體   English   中英

如何檢查數組是否包含 JavaScript 中的值?

[英]How do I check if an array includes a value in JavaScript?

找出 JavaScript 數組是否包含值的最簡潔有效的方法是什么?

這是我知道的唯一方法:

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

有沒有更好更簡潔的方法來完成這個?

這與 Stack Overflow 問題Best way to find an item in a JavaScript Array?密切相關。 它解決了使用indexOf在數組中查找對象的問題。

現代瀏覽器有Array#includes ,它正是這樣做的,並且得到了除 IE 之外的所有人的廣泛支持

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

您也可以使用Array#indexOf ,它不那么直接,但對於過時的瀏覽器不需要 polyfill。

 console.log(['joe', 'jane', 'mary'].indexOf('jane') >= 0); //true


許多框架也提供了類似的方法:

請注意,一些框架將其實現為一個函數,而另一些框架則將該函數添加到數組原型中。

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

indexOf可能,但它是“ECMA-262 標准的 JavaScript 擴展;因此它可能不存在於該標准的其他實現中。”

例子:

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

AFAICS Microsoft沒有為此提供某種替代方案,但如果您願意,您可以在 Internet Explorer(以及其他不支持indexOf的瀏覽器)中為數組添加類似的功能,正如Google 快速搜索所顯示的那樣(例如, 這個一)。

最重要的答案假定原始類型,但如果你想知道一個數組是否包含一個具有某種特征的對象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 支持表

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

與使用Strict Equality ComparisonindexOf不同,它includes使用SameValueZero相等算法的比較。 這意味着您可以檢測數組是否包含NaN

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

indexOf不同的是, includes不會跳過缺失的索引:

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

可以對其進行polyfill以使其適用於所有瀏覽器。

假設您已經定義了一個這樣的數組:

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

以下是檢查其中是否有3的三種方法。 它們都返回truefalse

Native Array 方法(自 ES2016 起)(兼容性表

array.includes(3) // true

作為自定義 Array 方法(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

這是Array.indexOfJavaScript 1.6 兼容實現:

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;
        };
}

利用:

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

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

擴展 JavaScript Array對象是一個非常糟糕的主意,因為您將新屬性(您的自定義方法)引入到for-in循環中,這可能會破壞現有腳本。 幾年前, Prototype庫的作者不得不重新設計他們的庫實現以刪除這種東西。

如果您不需要擔心與頁面上運行的其他 JavaScript 的兼容性,那就去吧,否則,我會推薦更笨拙但更安全的獨立函數解決方案。

表現

今天 2020.01.07 我在 Chrome v78.0.0、Safari v13.0.4 和 Firefox v71.0.0 上對 MacOs HighSierra 10.13.6 進行了 15 種選定解決方案的測試。 結論

  • 基於JSONSet和意外find (K,N,O) 的解決方案在所有瀏覽器上最慢
  • es6 includes (F) 僅在 chrome 上速度很快
  • 基於for (C,D) 和indexOf (G,H) 的解決方案在大小數組上的所有瀏覽器上都非常快,因此它們可能是有效解決方案的最佳選擇
  • 循環期間索引減少的解決方案,(B) 速度較慢可能是因為CPU 緩存的工作方式。
  • 當搜索的元素位於數組長度的 66% 位置時,我還對大數組進行了測試,基於for (C,D,E) 的解決方案給出了類似的結果(~630 ops/sec - 但 safari 和 firefox 上的 E 為 10 -20% 比 C 和 D 慢)

結果

在此處輸入圖像描述

細節

我執行 2 個測試用例:對於具有 10 個元素的數組和具有 100 萬個元素的數組。 在這兩種情況下,我們都將搜索到的元素放在數組中間。

 let log = (name,f) => console.log(`${name}: 3-${f(arr,'s10')} 's7'-${f(arr,'s7')} 6-${f(arr,6)} 's3'-${f(arr,'s3')}`) let arr = [1,2,3,4,5,'s6','s7','s8','s9','s10']; //arr = new Array(1000000).fill(123); arr[500000]=7; function A(a, val) { var i = -1; var n = a.length; while (i++<n) { if (a[i] === val) { return true; } } return false; } function B(a, val) { var i = a.length; while (i--) { if (a[i] === val) { return true; } } return false; } function C(a, val) { for (var i = 0; i < a.length; i++) { if (a[i] === val) return true; } return false; } function D(a,val) { var len = a.length; for(var i = 0 ; i < len;i++) { if(a[i] === val) return true; } return false; } function E(a, val){ var n = a.length-1; var t = n/2; for (var i = 0; i <= t; i++) { if (a[i] === val || a[ni] === val) return true; } return false; } function F(a,val) { return a.includes(val); } function G(a,val) { return a.indexOf(val)>=0; } function H(a,val) { return !!~a.indexOf(val); } function I(a, val) { return a.findIndex(x=> x==val)>=0; } function J(a,val) { return a.some(x=> x===val); } function K(a, val) { const s = JSON.stringify(val); return a.some(x => JSON.stringify(x) === s); } function L(a,val) { return !a.every(x=> x!==val); } function M(a, val) { return !!a.find(x=> x==val); } function N(a,val) { return a.filter(x=>x===val).length > 0; } function O(a, val) { return new Set(a).has(val); } log('A',A); log('B',B); log('C',C); log('D',D); log('E',E); log('F',F); log('G',G); log('H',H); log('I',I); log('J',J); log('K',K); log('L',L); log('M',M); log('N',N); log('O',O);
 This shippet only presents functions used in performance tests - it not perform tests itself!

小數組 - 10 個元素

您可以在您的機器上執行測試這里

在此處輸入圖像描述

大數組 - 1.000.000 個元素

您可以在您的機器上執行測試這里

在此處輸入圖像描述

單線:

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

開箱即用,如果您多次多次進行此調用,則使用 關聯數組 和 Map 使用散列函數進行查找會效率更高。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

我使用以下內容:

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

var a = [ 'foo', 'bar' ];

a.contains('foo'); // true
a.contains('fox'); // false
function contains(a, obj) {
    return a.some(function(element){return element == obj;})
}

Array.prototype.some()在第 5 版中被添加到 ECMA-262 標准中

如果您使用 JavaScript 1.6 或更高版本(Firefox 1.5 或更高版本),則可以使用Array.indexOf 否則,我認為您最終會得到類似於原始代碼的內容。

希望更快的雙向indexOf / lastIndexOf替代方案

2015

雖然新方法includes非常好,但目前支持基本上為零。

很長時間以來,我一直在想一種方法來替換緩慢的indexOf / lastIndexOf函數。

已經找到了一種高效的方法,查看最重要的答案。 從那些我選擇了@Damir Zekic 發布的contains功能,這應該是最快的。 但它也指出,基准是從 2008 年開始的,因此已經過時。

我也更喜歡while不是for ,但不是出於特定原因,我結束了用 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');

性能測試

https://jsbench.me/7el1b8dj80

作為測試,我創建了一個包含 100k 條目的數組。

三個查詢:在數組的開頭、中間和結尾。

我希望你也覺得這很有趣並測試性能。

注意:如您所見,我稍微修改了contains函數以反映indexOflastIndexOf輸出(因此index基本上為true-1false )。 那不應該傷害它。

數組原型變體

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');

該函數也可以很容易地修改為返回真或假,甚至返回對象、字符串或其他任何東西。

這是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');

這怎么可能?

我認為在數組中獲取反射索引的簡單計算非常簡單,它比執行實際循環迭代快兩倍。

這是一個復雜的示例,每次迭代執行三項檢查,但這只有通過更長的計算才能實現,這會導致代碼變慢。

https://web.archive.org/web/20151019160219/http://jsperf.com/bidirectionalindexof/2

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

如果找到則返回數組索引,如果未找到則返回 -1

我們使用這個片段(適用於對象、數組、字符串):

/*
 * @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

如果您反復檢查數組中是否存在對象,您可能應該查看

  1. 通過在數組中進行插入排序來保持數組始終排序(將新對象放在正確的位置)
  2. 將對象更新為刪除+排序插入操作和
  3. 在您的contains(a, obj)中使用二進制搜索查找。

適用於所有現代瀏覽器的解決方案:

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


使用 perf 優化更新了contains函數。 感謝itinance指出。

使用 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)

此要求的簡單解決方案是使用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');

如果數據為空,則沒有管理員,否則它將返回現有對象,例如:

{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"}];

雖然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 例如。)

ECMAScript 6 在 find 上有一個優雅的提議。

find 方法對數組中存在的每個元素執行一次回調函數,直到找到一個回調函數返回真值。 如果找到這樣的元素,find 立即返回該元素的值。 否則,find 返回 undefined。 回調僅針對已分配值的數組索引調用; 對於已被刪除或從未被賦值的索引,它不會被調用。

這是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;
    }
  });
}

可以使用具有“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'));

利用:

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

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

演示

要確切地知道tilde ~在這一點上做什么,請參閱這個問題當它在表達式之前時波浪號做什么? .

好的,你可以優化你的代碼來得到結果!

有很多方法可以做到這一點,更干凈,更好,但我只是想獲得你的模式並使用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;
}

驚訝於這個問題仍然沒有添加最新的語法,增加了我的 2 美分。

假設我們有一個對象數組 arrObj,我們想在其中搜索 obj。

數組.原型。 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

數組.原型。 包括-> (返回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

數組.原型。 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

數組.原型。 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 條件從數組中獲取任何對象(即使我們沒有引用)。

它有一個參數:一組對象數。 數組中的每個對象都有兩個整數屬性,分別用 x 和 y 表示。 該函數必須返回數組中滿足numbers.x == numbers.y的所有此類對象的計數

 var numbers = [ { x: 1, y: 1 }, { x: 2, y: 3 }, { x: 3, y: 3 }, { x: 3, y: 4 }, { x: 4, y: 5 } ]; var count = 0; var n = numbers.length; for (var i =0;i<n;i++) { if(numbers[i].x==numbers[i].y) {count+=1;} } alert(count);

 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);

使用Array.prototype.includes例如:

 const fruits = ['coconut', 'banana', 'apple'] const doesFruitsHaveCoconut = fruits.includes('coconut')// true console.log(doesFruitsHaveCoconut)

也許從 MDN 閱讀此文檔: https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

下面是Prototype 的做法

/**
 *  Array#indexOf(item[, offset = 0]) -> Number
 *  - item (?): A value that may or may not be in the array.
 *  - offset (Number): The number of initial items to skip before beginning the
 *      search.
 *
 *  Returns the position of the first occurrence of `item` within the array &mdash; or
 *  `-1` if `item` doesn't exist in the array.
**/
function indexOf(item, i) {
  i || (i = 0);
  var length = this.length;
  if (i < 0) i = length + i;
  for (; i < length; i++)
    if (this[i] === item) return i;
  return -1;
}

另請參閱此處了解他們如何連接它。

絕不是最好的,但我只是在發揮創造力並添加到曲目中。

不要使用這個

 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'));

  1. 要么使用Array.indexOf(Object)
  2. 使用 ECMA 7 可以使用Array.includes(Object)
  3. 使用 ECMA 6,您可以使用Array.find(FunctionName)其中FunctionName是用戶定義的函數來搜索數組中的對象。

    希望這可以幫助!

使用 indexOf()

您可以使用 indexOf() 方法檢查給定值或元素是否存在於數組中。 indexOf() 方法如果找到則返回數組內元素的索引,如果未找到則返回 -1。 讓我們看一下下面的例子:

 var fruits = ["Apple", "Banana", "Mango", "Orange", "Papaya"]; var a = "Mango"; checkArray(a, fruits); function checkArray(a, fruits) { // Check if a value exists in the fruits array if (fruits.indexOf(a) !== -1) { return document.write("true"); } else { return document.write("false"); } }

使用 include() 方法

ES6 引入了 includes() 方法來非常容易地執行此任務。 但是,此方法僅返回 true 或 false 而不是索引號:

 var fruits = ["Apple", "Banana", "Mango", "Orange", "Papaya"]; alert(fruits.includes("Banana")); // Outputs: true alert(fruits.includes("Coconut")); // Outputs: false alert(fruits.includes("Orange")); // Outputs: true alert(fruits.includes("Cherry")); // Outputs: false

如需進一步參考,請在此處結帳

有幾種方法可以輕松實現( includessomefind 、查找findIndex

 const array = [1, 2, 3, 4, 5, 6, 7]; console.log(array.includes(3)); //includes() determines whether an array includes a certain value among its entries console.log(array.some(x => x === 3)); //some() tests if at least one element in the array passes the test implemented by the provided function console.log(array.find(x => x === 3) ? true : false); //find() returns the value of the first element in the provided array that satisfies the provided testing function console.log(array.findIndex(x => x === 3) > -1); //findIndex() returns the index of the first element in the array that satisfies the provided testing function, else returning -1.

你也可以使用這個技巧:

var arrayContains = function(object) {
  return (serverList.filter(function(currentObject) {
    if (currentObject === object) {
      return currentObject
    }
    else {
      return false;
    }
  }).length > 0) ? true : false
}

正如其他人提到的,您可以使用Array.indexOf ,但並非在所有瀏覽器中都可用。 這是來自https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf的代碼,以使其在舊瀏覽器中的工作方式相同。

indexOf 是 ECMA-262 標准的最新補充; 因此,它可能不會出現在所有瀏覽器中。 您可以通過在腳本開頭插入以下代碼來解決此問題,允許在本機不支持它的實現中使用 indexOf。 該算法正是 ECMA-262 第 5 版中指定的算法,假設 Object、TypeError、Number、Math.floor、Math.abs 和 Math.max 具有其原始值。

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
        "use strict";
        if (this == null) {
            throw new TypeError();
        }
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = 0;
        if (arguments.length > 1) {
            n = Number(arguments[1]);
            if (n != n) { // shortcut for verifying if it's NaN
                n = 0;
            } else if (n != 0 && n != Infinity && n != -Infinity) {
                n = (n > 0 || -1) * Math.floor(Math.abs(n));
            }
        }
        if (n >= len) {
            return -1;
        }
        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
        for (; k < len; k++) {
            if (k in t && t[k] === searchElement) {
                return k;
            }
        }
        return -1;
    }
}

或者這個解決方案:

Array.prototype.includes = function (object) {
  return !!+~this.indexOf(object);
};

使用 idnexOf() 是一個很好的解決方案,但您應該隱藏嵌入式實現 indexOf() 函數,該函數使用 ~ 運算符返回 -1:

function include(arr,obj) { 
    return !!(~arr.indexOf(obj)); 
} 

我正在做一個項目,我需要一個像 python set這樣的功能,它可以刪除所有重復值並返回一個新列表,所以我寫了這個函數可能對某人有用

function set(arr) {
    var res = [];
    for (var i = 0; i < arr.length; i++) {
        if (res.indexOf(arr[i]) === -1) {
            res.push(arr[i]);
        }
    }
    return res;
}

如果您使用的是 ES6,您可以使用一組:

function arrayHas( array, element ) {
    const s = new Set(array);
    return s.has(element)
}

這應該比任何其他方法都更高效

我建議使用下划線庫,因為它返回值並支持所有瀏覽器。

下划線

 var findValue = _.find(array, function(item) {
    return item.id == obj.id;
 });

除了其他人所說的之外,如果您沒有要在數組中搜索的對象的引用,那么您可以執行類似的操作。

let array = [1, 2, 3, 4, {"key": "value"}];

array.some((element) => JSON.stringify(element) === JSON.stringify({"key": "value"})) // true

array.some((element) => JSON.stringify(element) === JSON.stringify({})) // true

如果任何元素與給定條件匹配,則 Array.some 返回 true,如果沒有任何元素與給定條件匹配,則返回 false。

Object.keys用於獲取對象的所有屬性名稱並過濾與指定字符串完全或部分匹配的所有值。

 function filterByValue(array, string) { return array.filter(o => Object.keys(o).some(k => o[k].toLowerCase().includes(string.toLowerCase()))); } const arrayOfObject = [{ name: 'Paul', country: 'Canada', }, { name: 'Lea', country: 'Italy', }, { name: 'John', country: 'Italy' }]; console.log(filterByValue(arrayOfObject, 'lea')); // [{name: 'Lea', country: 'Italy'}] console.log(filterByValue(arrayOfObject, 'ita')); // [{name: 'Lea', country: 'Italy'}, {name: 'John', country: 'Italy'}]

您還可以按特定鍵進行過濾,例如。

Object.keys(o).some(k => o.country.toLowerCase().includes(string.toLowerCase())));

現在您可以在過濾后檢查數組計數以檢查值是否包含。

希望它有幫助。

將唯一項目添加到另一個列表

searchResults: [
                {
                    name: 'Hello',
                    artist: 'Selana',
                    album: 'Riga',
                    id: 1,
                },
                {
                    name: 'Hello;s',
                    artist: 'Selana G',
                    album: 'Riga1',
                    id: 2,
                },
                {
                    name: 'Hello2',
                    artist: 'Selana',
                    album: 'Riga11',
                    id: 3,
                }
            ],
            playlistTracks: [
              {
                name: 'Hello',
                artist: 'Mamunuus',
                album: 'Riga',
                id: 4,
              },
              {
                name: 'Hello;s',
                artist: 'Mamunuus G',
                album: 'Riga1',
                id: 2,
              },
              {
                name: 'Hello2',
                artist: 'Mamunuus New',
                album: 'Riga11',
                id: 3,
              }
            ],
            playlistName: "New PlayListTrack",
        };
    }

    // Adding an unique track in the playList
    addTrack = track => {
      if(playlistTracks.find(savedTrack => savedTrack.id === track.id)) {
        return;
      }
      playlistTracks.push(track);

      this.setState({
        playlistTracks
      })
    };

這可能是一個詳細而簡單的解決方案。

//plain array
var arr = ['a', 'b', 'c'];
var check = arr.includes('a');
console.log(check); //returns true
if (check)
{
   // value exists in array
   //write some codes
}

// array with objects
var arr = [
      {x:'a', y:'b'},
      {x:'p', y:'q'}
  ];

// if you want to check if x:'p' exists in arr
var check = arr.filter(function (elm){
    if (elm.x == 'p')
    {
       return elm; // returns length = 1 (object exists in array)
    }
});

// or y:'q' exists in arr
var check = arr.filter(function (elm){
    if (elm.y == 'q')
    {
       return elm; // returns length = 1 (object exists in array)
    }
});

// if you want to check, if the entire object {x:'p', y:'q'} exists in arr
var check = arr.filter(function (elm){
    if (elm.x == 'p' && elm.y == 'q')
    {
       return elm; // returns length = 1 (object exists in array)
    }
});

// in all cases
console.log(check.length); // returns 1

if (check.length > 0)
{
   // returns true
   // object exists in array
   //write some codes
}

檢查數組 JavaScript 中是否存在值的最佳默認方法是some()

Array.prototype.some()

some()方法測試數組中的至少一個元素是否通過了提供的函數實現的測試。 如果在數組中找到所提供函數為其返回 true 的元素,則返回 true; 否則返回false。 它不會修改數組。

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

// checks whether an element is even
const even = (element) => element % 2 === 0;

console.log(array.some(even));
// expected output: true

some方法是瀏覽器兼容性最好的方法瀏覽器兼容性

更多文檔Array.prototype.some() - JavaScript | MDN

您也可以使用其他兩種方法find()includes() 使用這些方法,您可以獲得結果,但不是最好的。

Array.prototype.find() - JavaScript | MDN

Array.prototype.includes() - JavaScript | MDN

利用:

Array.prototype.contains = function(x){
  var retVal = -1;

  // x is a primitive type
  if(["string","number"].indexOf(typeof x)>=0 ){ retVal = this.indexOf(x);}

  // x is a function
  else if(typeof x =="function") for(var ix in this){
    if((this[ix]+"")==(x+"")) retVal = ix;
  }

  //x is an object...
  else {
    var sx=JSON.stringify(x);
    for(var ix in this){
      if(typeof this[ix] =="object" && JSON.stringify(this[ix])==sx) retVal = ix;
    }
  }

  //Return False if -1 else number if numeric otherwise string
  return (retVal === -1)?false : ( isNaN(+retVal) ? retVal : +retVal);
}

我知道這不是最好的方法,但是由於沒有原生的 IComparable 方式來在對象之間進行交互,我想這與比較數組中的兩個實體一樣接近。 此外,擴展 Array 對象可能不是明智之舉,但有時也可以(如果您意識到這一點並進行權衡)。

我查看了提交的答案,發現它們僅在您通過參考搜索對象時適用。 帶有參考對象比較的簡單線性搜索。

但是假設您沒有對對象的引用,您將如何在數組中找到正確的對象? 您將不得不對每個對象進行線性和深度比較。 想象一下,如果列表太大,並且其中的對象非常大,包含大量文本。 性能隨着數組中元素的數量和大小而急劇下降。

您可以對對象進行字符串化並將它們放入本機哈希表中,但是您將有數據冗余記住這些鍵,因為 JavaScript 將它們保留為“for i in obj”,並且您只想檢查對象是否存在,即,你有鑰匙。

我考慮了一段時間來構建一個 JSON Schema 驗證器,我為本地哈希表設計了一個簡單的包裝器,類似於唯一的哈希表實現,但有一些優化異常,我留給本地哈希表處理。 它只需要性能基准測試......所有細節和代碼都可以在我的博客上找到:http: //stamat.wordpress.com/javascript-quickly-find-very-large-objects-in-a-large-array/我將很快發布基准測試結果。

完整的解決方案是這樣工作的:

var a = {'a':1,
 'b':{'c':[1,2,[3,45],4,5],
 'd':{'q':1, 'b':{'q':1, 'b':8},'c':4},
 'u':'lol'},
 'e':2};

 var b = {'a':1, 
 'b':{'c':[2,3,[1]],
 'd':{'q':3,'b':{'b':3}}},
 'e':2};

 var c = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

 var hc = new HashCache([{a:3, b:2, c:5}, {a:15, b:2, c:'foo'}]); //init

 hc.put({a:1, b:1});
 hc.put({b:1, a:1});
 hc.put(true);
 hc.put('true');
 hc.put(a);
 hc.put(c);
 hc.put(d);
 console.log(hc.exists('true'));
 console.log(hc.exists(a));
 console.log(hc.exists(c));
 console.log(hc.exists({b:1, a:1}));
 hc.remove(a);
 console.log(hc.exists(c));

類似的事情:通過“搜索 lambda”查找第一個元素:

Array.prototype.find = function(search_lambda) {
  return this[this.map(search_lambda).indexOf(true)];
};

用法:

[1,3,4,5,8,3,5].find(function(item) { return item % 2 == 0 })
=> 4

在咖啡腳本中相同:

Array.prototype.find = (search_lambda) -> @[@map(search_lambda).indexOf(true)]

簡單的解決方案:ES6 Features " includes " 方法

let arr = [1, 2, 3, 2, 3, 2, 3, 4];

  arr.includes(2) // true

  arr.includes(93) // false

有幾種方法可以找出答案。 您可以使用內置的數組方法。 最常用的是數組查找方法。

const arr1 = [1, 2, 3, 4, 5]
const result = arr1.find(ele => ele === 4)
console.log(result) //4

const result2 = arr1.find(ele => ele === 6)
console.log(result2) //undefined
/* 
If the element is present inside the array
then it will return the first element that
satisfies the given condition. Otherwise
undefined will return.
*/

您可以使用 findIndex 函數來檢查數組是否具有特定值。

arrObj.findIndex(obj => obj === comparedValue) !== -1;

如果 arrObj 包含 compareValue,則返回 true,否則返回 false。

使用正則表達式:

console.log(new RegExp('26242').test(['23525', '26242', '25272'].join(''))) // true

如果您只是想檢查一個值是否包含在集合中,使用Set會更合適,因為Arrays可以有重復的值,而Sets不能。 此外,用set.has替換array.includes將性能從 O(n 2 ) 提高到 O(n)。 當您必須為同一個 Set 查找多個值時,這將很有用。 因此,如果您只想查找單個值,則使用set.has沒有任何好處,您可以只使用array.includes

創建了一個jsbench演示,您可以運行它來檢查性能。

測試執行截圖

在此處輸入圖像描述

Javascript 中查找數組是否包含值的最快方法是:

function existsInArrayForIgnoreDataType(arr, targetElem) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] == targetElem) return true
  }
  return false
 }

您可以在此處找到我所做的完整研究。

let isExistOrNot = (arr, element)=>{
    return arr.includes(element);
    // includes check that an element is included or not in an array
    // it return a boolean value true or false
}

let array = ['apple', 'ball', 'cat', 'dog']

console.log(isExistOrNot(array, 'yellow'));
//Result false because yellow doesn't exist in array
console.log(isExistOrNot(array, 'apple'));
//Result true because yellow exist in array

字面上地:

(使用 Firefox v3.6,帶有前面提到的for-in警告(但是,出於這個目的,下面的使用可能會支持for-in !也就是說,通過屬性索引枚舉實際存在的數組元素(但是,特別是數組length屬性未在for-in屬性列表中枚舉!)。)。)

(拖放以下完整 URI 以進行即時模式瀏覽器測試。)

JavaScript:

  function ObjInRA(ra){var has=false; for(i in ra){has=true; break;} return has;}

  function check(ra){
      return ['There is ',ObjInRA(ra)?'an':'NO',' object in [',ra,'].'].join('')
  }
  alert([
            check([{}]), check([]), check([,2,3]),
            check(['']), '\t (a null string)', check([,,,])
        ].join('\n'));

顯示:

There is an object in [[object Object]].
There is NO object in [].
There is an object in [,2,3].
There is an object in [].
     (a null string)
There is NO object in [,,].

皺紋:如果尋找“特定”對象,請考慮:

JavaScript: alert({}!={}); alert({}!=={}); alert({}!={}); alert({}!=={});

因此:

JavaScript:

 obj = {prop:"value"}; 
 ra1 = [obj]; 
 ra2 = [{prop:"value"}];
 alert(ra1[0] == obj); 
 alert(ra2[0] == obj);

通常ra2被認為“包含” obj作為文字實體{prop:"value"}

一個非常粗略、基本、幼稚(如代碼需要資格增強)的解決方案:

JavaScript:

  obj={prop:"value"};   ra2=[{prop:"value"}];
  alert(
    ra2 . toSource() . indexOf( obj.toSource().match(/^.(.*).$/)[1] ) != -1 ?
      'found' :
      'missing' );

請參閱參考: 在 JavaScript 數組中搜索對象

只是另一種選擇

// usage: if ( ['a','b','c','d'].contains('b') ) { ... }
Array.prototype.contains = function(value){
    for (var key in this)
        if (this[key] === value) return true;
    return false;
}

請小心,因為使用自定義方法重載 javascript 數組對象可能會破壞其他 javascript 的行為,從而導致意外行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM