Jak sprawdzić, czy tablica zawiera wartość w JavaScript?

Jaki jest najbardziej zwięzły i skuteczny sposób, aby dowiedzieć się, czy tablica JavaScript zawiera wartość?

To jedyny sposób, jaki znam, aby to zrobić:

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}
Czy istnieje lepszy i bardziej zwięzły sposób, aby to osiągnąć?
Author: Ry-, 2008-10-25

30 answers

Współczesne przeglądarki mają Array#includes, co czyni dokładnie że i jest szeroko wspierane przez wszystkich oprócz IE:

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

Możesz również użyć Array#indexOf, co jest mniej bezpośrednie, ale nie wymaga polyfills dla przestarzałych przeglądarek.

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

Wiele frameworków oferuje również podobne metody:]}

Zauważ, że niektóre frameworki implementują to jako funkcję, podczas gdy inne dodają funkcję do tablicy prototyp.

 4702
Author: codeape,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-03 17:51:42

Aktualizacja z 2019: ta odpowiedź pochodzi z 2008 (11 lat!) i nie ma znaczenia dla współczesnego użytkowania JS. Obiecana poprawa wydajności została oparta na benchmarku wykonanym w ówczesnych przeglądarkach. Może to nie być istotne dla współczesnych kontekstów wykonywania JS. Jeśli potrzebujesz łatwego rozwiązania, poszukaj innych odpowiedzi. Jeśli potrzebujesz najlepszej wydajności, sam dokonaj testów porównawczych w odpowiednich środowiskach wykonawczych.

Jak mówili inni, iteracja przez tablicę jest prawdopodobnie najlepszym sposobem, ale udowodniono , że zmniejszająca się pętla while jest najszybszym sposobem iteracji w JavaScript. Możesz więc przepisać swój kod w następujący sposób:

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

Oczywiście równie dobrze możesz rozszerzyć prototyp tablicy:

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

A teraz możesz po prostu użyć następującego:

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false
 456
Author: Damir Zekić,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-07 10:49:03

indexOf może, ale jest to " rozszerzenie JavaScript do standardu ECMA-262; jako takie może nie być obecne w innych implementacjach standardu."

Przykład:

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

AFAICS Microsoft nie oferuje jakiejś alternatywy do tego, ale możesz dodać podobną funkcjonalność do tablic w Internet Explorerze (i innych przeglądarkach, które nie obsługują indexOf), jeśli chcesz, ponieważ szybkie wyszukiwanie Google ujawnia (na przykład, to jeden ).

 220
Author: cic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-11 23:41:11

ECMAScript 7 wprowadza Array.prototype.includes.

Można go używać w następujący sposób:

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

Przyjmuje również opcjonalny drugi argument fromIndex:

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

W przeciwieństwie do indexOf, który używa ścisłego porównania równości, includes porównuje za pomocą algorytmu równości SameValueZero. Oznacza to, że możesz wykryć, czy tablica zawiera NaN:

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

Również w przeciwieństwie do indexOf, includes nie pomija brakujących indeksów:

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

Obecnie jest to jeszcze szkic ale może być polyfilled , aby działał na wszystkich przeglądarkach.

 179
Author: Oriol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 16:53:32

Najlepsze odpowiedzi przyjmują prymitywne typy, ale jeśli chcesz dowiedzieć się, czy tablica zawiera obiekt z jakąś cechą, tablica.prototyp.niektóre () {[8] } to eleganckie rozwiązanie:

const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]

items.some(item => item.a === '3')  // returns true
items.some(item => item.a === '4')  // returns false

Fajną rzeczą jest to, że iteracja jest przerywana, gdy element zostanie znaleziony, więc niepotrzebne cykle iteracji są oszczędzane.

Pasuje również do instrukcji if, ponieważ zwraca wartość logiczną:

if (items.some(item => item.a === '3')) {
  // do something
}

* Jak zauważył jamess w komentarzu, w czasie tej odpowiedzi, Wrzesień 2018, Array.prototype.some() jest w pełni obsługiwane: caniuse.com tabela wsparcia

 163
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-24 11:39:15

Powiedzmy, że zdefiniowałeś tablicę tak:

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

Poniżej znajdują się trzy sposoby sprawdzenia, czy w środku jest 3. Wszystkie zwracają true lub false.

Native Array method (since ES2016) (compatibility table)

array.includes(3) // true

Jako metoda tablicy niestandardowej (pre 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

Prosta funkcja

const includes = (a, v) => a.indexOf(v) !== -1
includes(array, 3) // true
 117
Author: william malo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-13 17:09:22

Oto JavaScript 1.6 zgodny implementacja Array.indexOf:

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;
        };
}
 83
Author: Már Örlygsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-30 10:23:54

Użycie:

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

// Usage
if(isInArray(my_array, "my_value"))
{
    //...
}
 59
Author: Matías Cánepa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-07 11:29:04

Rozszerzenie obiektu JavaScript Array jest naprawdę złym pomysłem, ponieważ wprowadzasz nowe właściwości (własne metody) do pętli for-in, które mogą łamać istniejące Skrypty. Kilka lat temu autorzy prototyp biblioteki musieli przeprojektować implementację biblioteki, aby usunąć tego typu rzeczy.

Jeśli nie musisz martwić się o kompatybilność z innymi JavaScript uruchomionych na stronie, idź do niego, w przeciwnym razie, polecam bardziej niewygodne, ale bezpieczniejsze rozwiązanie funkcji wolnostojącej.

 53
Author: Peter Mortensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-11 23:43:55

One-liner:

function contains(arr, x) {
    return arr.filter(function(elem) { return elem == x }).length > 0;
}
 34
Author: AlonL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-07 11:25:51

Myśląc przez chwilę po wyjęciu z pudełka, jeśli wykonujesz to wywołanie wiele razy, znacznie bardziej wydajne jest użycie tablicy asocjacyjnej mapy do wyszukiwania za pomocą funkcji hash.

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

 33
Author: MattMcKnight,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-06 18:35:49

Wydajność

Dzisiaj 2020.01.07 wykonuję testy na MacOs HighSierra 10.13.6 na Chrome v78.0.0, Safari v13.0.4 i Firefox v71.0.0 dla 15 wybranych rozwiązań. Wnioski

  • rozwiązania oparte na JSON, Set i zaskakująco find (K, N, O) są najwolniejsze we wszystkich przeglądarkach
  • es6 includes (F) jest szybki tylko na chrome
  • rozwiązania oparte na for (C,D) i indexOf (G,H) są dość szybkie we wszystkich przeglądarkach na małych i dużych tablicach, więc prawdopodobnie są najlepszym wyborem dla efektywnego rozwiązania
  • rozwiązania, w których indeks zmniejsza się podczas pętli, (B) są wolniejsze prawdopodobnie dlatego, że sposób działania Cache CPU działa.
  • wykonuję również test dla dużych tablic, gdy szukany element znajdował się na pozycji 66% długości tablicy, a rozwiązania bazujące na for (C, D, E) dają podobne wyniki (~630 ops/sek - ale E na safari i Firefoksie było o 10-20% wolniejsze niż C i D)

Wyniki

Tutaj wpisz opis obrazka

Szczegóły

Wykonuję 2 przypadki testowe: dla tablicy z 10 elementami i tablicy z 1 milionem elementów. W obu przypadkach umieszczamy wyszukiwany element w środku tablicy.

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[n-i] === 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!

Tablica mała-10 elementów

Możesz wykonać testy w swojej maszynie tutaj

Tutaj wpisz opis obrazka

Tablica duża - 1.000.000 elementów

Możesz wykonać testy w swojej maszynie tutaj

Tutaj wpisz opis obrazka

 29
Author: Kamil Kiełczewski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-11 16:26:33

Używam:

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

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

a.contains('foo'); // true
a.contains('fox'); // false
 28
Author: Eduardo Cuomo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-15 01:15:33
function contains(a, obj) {
    return a.some(function(element){return element == obj;})
}

/ align = "left" / prototyp.niektóre () zostały dodane do standardu ECMA-262 w piątej edycji

 24
Author: dansalmo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-12 16:55:36

Mam nadzieję, że szybszy dwukierunkowy indexOf / lastIndexOf alternatywa

2015

Podczas gdy nowa metoda zawiera jest bardzo ładna, wsparcie jest w zasadzie zero na razie.

Długo myślałem o sposobie zastąpienia powolnych funkcji indexOf/lastIndexOf.

Znaleziono już sposób wykonania, patrząc na najlepsze odpowiedzi. Z nich wybrałem funkcję contains napisaną przez @ Damir Zekic, która powinna być najszybsza. Ale także stwierdza, że poziomy odniesienia pochodzą z 2008 r. i dlatego są nieaktualne.

Ja też wolę while niż for, ale z nie konkretnego powodu zakończyłem pisanie funkcji pętlą for. Można to również zrobić za pomocą while --.

Byłem ciekaw, czy iteracja jest znacznie wolniejsza, jeśli sprawdzam obie strony tablicy podczas jej wykonywania. Widocznie nie, a więc ta funkcja jest około dwa razy szybsza od najlepszych. Oczywiście jest też szybszy od rodzimego. To w prawdziwym świecie środowisko, w którym nigdy nie wiadomo, czy szukana wartość znajduje się na początku czy na końcu tablicy.

Kiedy wiesz, że właśnie wypchnąłeś tablicę z wartością, użycie lastIndexOf pozostaje prawdopodobnie najlepszym rozwiązaniem, ale jeśli musisz podróżować przez duże tablice, a wynik może być wszędzie, może to być solidne rozwiązanie, aby przyspieszyć działanie.

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

Wydajność test

Http://jsperf.com/bidirectionalindexof

Jako test stworzyłem tablicę ze 100k wpisami.

Trzy zapytania: na początku, w środku i na końcu tablicy.

Mam nadzieję, że również uznacie to za interesujące i przetestujecie wydajność.

Uwaga: jak widzisz nieznacznie zmodyfikowałem funkcję contains, aby odzwierciedlała wyjście indexOf & lastIndexOf (więc zasadniczo true z index i false z -1). To nie powinno zaszkodzić to.

Wariant prototypu tablicy

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

Funkcja może być również łatwo zmodyfikowana, aby zwracać true lub false, a nawet obiekt, łańcuch lub cokolwiek to jest.

A oto wariant 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');
Jak to możliwe?

Myślę, że proste obliczenie, aby uzyskać odzwierciedlony indeks w tablicy jest tak proste, że jest dwa razy szybsze niż wykonanie rzeczywistej iteracji pętli.

Oto złożony przykład wykonywania trzech kontroli na iteracji, ale jest to możliwe tylko przy dłuższych obliczeniach, co powoduje spowolnienie kodu.

Http://jsperf.com/bidirectionalindexof/2

 19
Author: cocco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-07 11:42:35

Jeśli używasz JavaScript 1.6 lub nowszego (Firefox 1.5 lub nowszego), możesz użyć tablicy .indexOf . W przeciwnym razie, myślę, że skończysz z czymś podobnym do oryginalnego kodu.

 17
Author: Andru Luvisi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-25 22:44:57
function inArray(elem,array)
{
    var len = array.length;
    for(var i = 0 ; i < len;i++)
    {
        if(array[i] == elem){return i;}
    }
    return -1;
} 

Zwraca indeks tablicy, jeśli zostanie znaleziony, lub -1, jeśli nie zostanie znaleziony

 17
Author: LmC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-06 16:22:05

Jeśli sprawdzasz wielokrotnie istnienie obiektu w tablicy, powinieneś zajrzeć do

  1. utrzymywanie sortowania tablicy przez cały czas wykonując sortowanie wstawiania w tablicy (umieszczanie nowych obiektów w odpowiednim miejscu)
  2. Make updating objects as remove+posorted insert operation and
  3. Użyj wyszukiwania binarnego w contains(a, obj).
 16
Author: Ztyx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-05 18:02:43

Używamy tego fragmentu (działa z obiektami, tablicami, łańcuchami):

/*
 * @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
});

Użycie:

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
 16
Author: dr.dimitru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-10 12:12:52

Rozwiązanie, które działa we wszystkich nowoczesnych przeglądarkach:

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

Użycie:

contains([{a: 1}, {a: 2}], {a: 1}); // true

IE6+ rozwiązanie:

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

Użycie:

contains([{a: 1}, {a: 2}], {a: 1}); // true

Dlaczego używać JSON.stringify?

Array.indexOf i Array.includes (jak również większość odpowiedzi tutaj) porównać tylko przez odniesienie, a nie przez wartość.

[{a: 1}, {a: 2}].includes({a: 1});
// false, because {a: 1} is a new object

Bonus

Nie zoptymalizowany ES6 jednowierszowy:

[{a: 1}, {a: 2}].some(item => JSON.stringify(item) === JSON.stringify({a: 1));
// true

Uwaga: Porównywanie obiektów według wartości będzie działać lepiej, jeśli klucze są w tej samej kolejności, więc dla bezpieczeństwa można sortować klucze najpierw z pakietem takim jak ten: https://www.npmjs.com/package/sort-keys


Zaktualizowano funkcję contains o optymalizację perf. Dzięki za wskazówkę.

 15
Author: Igor Barbashin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-04 23:34:23

Użyj funkcji lodash , .

Jest zwięzły, dokładny i ma świetne wsparcie między platformami.

Przyjęta odpowiedź nie spełnia nawet wymagań.

wymagania: zalecam najbardziej zwięzły i skuteczny sposób, aby dowiedzieć się, czy tablica JavaScript zawiera obiekt.

Zaakceptowana Odpowiedź:

$.inArray({'b': 2}, [{'a': 1}, {'b': 2}])
> -1

Moja rekomendacja:

_.some([{'a': 1}, {'b': 2}], {'b': 2})
> true

Uwagi:

$.inArray działa dobrze w celu ustalenia, czy Skalar wartość istnieje w tablicy skalarów...

$.inArray(2, [1,2])
> 1

... ale pytanie wyraźnie pyta o skuteczny sposób określenia, czy obiekt jest zawarty w tablicy.

Aby obsłużyć zarówno Skalary, jak i Obiekty, możesz to zrobić:

(_.isObject(item)) ? _.some(ary, item) : (_.indexOf(ary, item) > -1)
 12
Author: l3x,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-21 11:58:14

ECMAScript 6 ma elegancką propozycję na find.

Metoda find wykonuje funkcję wywołania zwrotnego raz dla każdego elementu obecny w tablicy, dopóki nie znajdzie takiej, w której callback zwraca true wartość. Jeśli taki element zostanie znaleziony, find natychmiast zwraca wartość tego pierwiastka. W przeciwnym razie find zwraca undefined. callback jest wywoływane tylko dla indeksów tablicy, które mają przypisane wartości; to nie jest wywoływany dla indeksów, które zostały usunięte lub które nigdy przypisano wartości.

Oto dokumentacja MDN na ten temat.

Funkcja Znajdź działa w ten sposób.

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

Możesz użyć tego w ECMAScript 5 i poniżej przez zdefiniowanie funkcji.

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;
    }
  });
}
 10
Author: Pradeep Mahdevu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-07 11:27:22

Podczas gdy array.indexOf(x)!=-1 jest najbardziej zwięzły sposób, aby to zrobić (i jest obsługiwany przez przeglądarki Nie - Internet Explorer od ponad dekady...), to nie jest O(1), ale raczej O(N), co jest straszne. Jeśli tablica nie będzie się zmieniać, możesz przekonwertować tablicę na hashtable, następnie wykonaj table[x]!==undefined lub ===undefined:

Array.prototype.toTable = function() {
    var t = {};
    this.forEach(function(x){t[x]=true});
    return t;
}

Demo:

var toRemove = [2,4].toTable();
[1,2,3,4,5].filter(function(x){return toRemove[x]===undefined})

(niestety, podczas gdy można utworzyć tablicę.prototyp.zawiera, aby" zamrozić " tablicę i zapisać w niej hashtable._cache w dwóch linijkach, dałoby to błędne wyniki jeśli później zdecydujesz się edytować tablicę. JavaScript ma niewystarczające Hooki, aby utrzymać ten stan, w przeciwieństwie do Pythona na przykład.)

 10
Author: ninjagecko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-07 11:30:42

Można użyć zestawu , który ma metodę " has ()":

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'));
 9
Author: rlib,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-24 12:16:00

Użycie:

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

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

Demo

Aby dokładnie wiedzieć, co tilde ~ czy w tym momencie, odnieść się do tego pytania co robi tylda, gdy poprzedza wyrażenie?.

 8
Author: Mina Gabriel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:09

OK, możesz po prostu zoptymalizować swój kod, Aby uzyskać wynik!

Istnieje wiele sposobów, aby to zrobić, które są czystsze i lepsze, ale po prostu chciałem uzyskać Twój wzór i zastosować do tego za pomocą JSON.stringify, po prostu zrób coś takiego w Twoim przypadku: {]}

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (JSON.stringify(a[i]) === JSON.stringify(obj)) {
            return true;
        }
    }
    return false;
}
 7
Author: Alireza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-06 14:48:58

Prostym rozwiązaniem tego wymogu jest użycie find()

Jeśli masz tablicę obiektów jak poniżej,

var users = [{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "admin"},
{id: "105", name: "user"}];

Następnie możesz sprawdzić, czy obiekt z Twoją wartością jest już obecny czy nie

let data = users.find(object => object['id'] === '104');

Jeśli data jest null, to no admin, w przeciwnym razie zwróci istniejący obiekt jak poniżej.

{id: "104", name: "admin"}

Następnie możesz znaleźć indeks tego obiektu w tablicy i zastąpić go poniższym kodem.

let indexToUpdate = users.indexOf(data);
let newObject = {id: "104", name: "customer"};
users[indexToUpdate] = newObject;//your new object
console.log(users);

Otrzymasz wartość jak poniżej

[{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "customer"},
{id: "105", name: "user"}];
Mam nadzieję, że to pomoże komukolwiek.
 7
Author: Shiva,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-11 17:38:31

Bynajmniej nie najlepszy, ale zaczynałem być kreatywny i dodawać do repertuaru.

Nie używaj tego

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'));
 6
Author: sqram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Dziwne, że to pytanie wciąż nie ma najnowszej składni dodanej, dodając moje 2 grosze.

Załóżmy, że mamy tablicę obiektów arrObj i chcemy przeszukać w niej obj.

Array.prototyp.indexOf -> (zwraca index lub -1) jest zwykle używany do znajdowania indeksu elementu w tablicy. Może być również używany do wyszukiwania obiektu, ale działa tylko wtedy, gdy przekazujesz odwołanie do tego samego obiektu.

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

Array.prototyp.zawiera -> (zwraca true or false )

console.log(arrObj.includes(obj));  //true
console.log(arrObj.includes({ name: 'Sumer', age: 36 })); //false

console.log([1, 3, 5, 2].includes(2)); //true

Array.prototyp.find - > (pobiera callback, zwraca najpierw wartość / obiekt który zwraca true w CB).

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

Array.prototyp.findIndex - > (pobiera callback, zwraca index pierwszej wartości / obiektu, który zwraca true w CB).

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

Ponieważ find I findIndex pobiera wywołanie zwrotne, możemy pobrać dowolny obiekt (nawet jeśli nie mamy referencji) z tablicy poprzez twórcze ustawienie true warunek.

 6
Author: Sumer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-07 13:42:50

    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);
 6
Author: Sanjay Magar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-24 12:01:13