Weboldal keresés

Hogyan ellenőrizhetem, hogy egy tömb tartalmaz-e egy értéket JavaScript-ben?


Mi a legtömörebb és leghatékonyabb módja annak, hogy kiderítsük, tartalmaz-e egy JavaScript tömb egy értéket?

Ez az egyetlen mód, ahogy tudom csinálni:

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

Van jobb és tömörebb módja ennek elvégzésére?

Ez szorosan kapcsolódik a Stack Overflow kérdéshez A legjobb módja egy elem megtalálásának egy JavaScript tömbben?, amely a indexOf használatával történő objektumkeresést tárgyalja egy tömbben.

Válasz #1

A modern böngészők rendelkeznek Array#includes-szal, ami pontosan ezt csinálja, és mindenki által széles körben támogatott, kivéve az IE-t:

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

Használhatja az Array#indexOf metódust is, ami kevésbé közvetlen, de nem igényel polyfilleket elavult böngészőkhöz.

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

Sok keretrendszer hasonló módszereket is kínál:

  • jQuery: $.inArray(érték, tömb, [fromIndex])
  • Underscore.js: _.contains(array, value) (más néven _.include és _.includes)
  • Dojo Toolkit: dojo.indexOf(array, value, [fromIndex, findLast])
  • Prototípus: array.indexOf(value)
  • MooTools: array.indexOf(value)
  • MochiKit: findValue(tömb, érték)
  • MS Ajax: array.indexOf(érték)
  • Ext: Ext.Array.contains(array, value)
  • Lodash: _.includes(array, value, [from]) (a _.contains 4.0.0 előtt)
  • Ramda: R.includes(érték, tömb)

Vegye észre, hogy egyes keretrendszerek ezt függvényként valósítják meg, míg mások a függvényt az tömb prototípusához adják.

Válasz #2

Frissítés 2019-ből: Ez a válasz 2008-ból származik (11 éves!) és nem releváns a modern JS használatában. A megígért teljesítményjavulás azon a teszten alapult, amelyet akkoriban a böngészőkben végeztek. Lehet, hogy nem releváns a modern JS futtatási környezetekre. Ha könnyű megoldást keresel, nézz utána más válaszoknak. Ha a legjobb teljesítményt szeretnéd, teszteld magad a megfelelő futtatási környezetekben.

Ahogy mások is mondták, a tömbön való iterálás valószínűleg a legjobb mód, de bebizonyosodott, hogy a csökkenő while ciklus a leggyorsabb mód a JavaScript-ben való iterálásra. Tehát érdemes lehet a kódodat a következőképpen átírni:

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

Természetesen bővítheted az Array prototípusát is:

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

És most egyszerűen használhatod a következőt:

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false

Válasz #3

A legjobb válaszok primitív típusokat feltételeznek, de ha meg akarod találni, hogy egy tömb objektumot tartalmaz-e valamilyen tulajdonsággal, az Array.prototype.some() elegáns megoldás:

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

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

Az az jó benne, hogy az iteráció megszakad, amint az elemet megtalálják, így a felesleges iterációs ciklusokat meg lehet spórolni.

Emellett szépen illeszkedik egy if utasításba, mivel logikai értéket ad vissza:

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

* Ahogy jamess rámutatott a hozzászólásban, ennek a válasznak az idején, 2018 szeptemberében, a Array.prototype.some() teljesen támogatott: caniuse.com támogatási táblázat

Válasz #4

indexOf talán, de ez egy „JavaScript kiterjesztés az ECMA-262 szabványhoz; mint ilyen, előfordulhat, hogy nem jelenik meg a szabvány más implementációiban.”

Példa :

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

AFAICS a Microsoft nem kínál valamilyen alternatívát erre, de hozzáadhatsz hasonló funkciót a tömbökhöz az Internet Explorerben (és más böngészőkben, amelyek nem támogatják a indexOf-t), ha szeretnéd, ahogy egy gyors Google-keresés is megmutatja (például ez).

Válasz #5

Az ECMAScript 7 bevezeti az Array.prototype.includes metódust.

Így lehet használni:

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

Ez egy opcionális második argumentumot is elfogad, fromIndex:

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

Ellentétben a indexOf-dal, amely Szigorú Egyenlőség-összehasonlítást használ, a includes a SameValueZero egyenlőség algoritmust alkalmazza. Ez azt jelenti, hogy észreveheted, ha egy tömb tartalmaz NaN-t:

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

Szintén, a indexOf-tól eltérően, a includes nem hagyja figyelmen kívül a hiányzó indexeket:

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

Polyfill-lel lehet kiegészíteni, hogy minden böngészőn működjön.

Válasz #6

Tegyük fel, hogy így definiáltál egy tömböt:

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

Az alábbiakban három módja van annak ellenőrzésére, hogy van-e benne 3. Mindegyik true vagy false értéket ad vissza.

Beépített tömb metódus (2016-tól, ES2016) (kompatibilitási táblázat)

array.includes(3) // true

Egyedi Array metódus (ES2016 előtt)

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

Egyszerű függvény

const includes = (a, v) => a.indexOf(v) !== -1
includes(array, 3) // true

Válasz #7

Íme egy JavaScript 1.6 kompatibilis megvalósítása az Array.indexOf-nak:

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

Válasz #8

Használat :

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

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

Válasz #9

A JavaScript Array objektum kiterjesztése valóban rossz ötlet, mert új tulajdonságokat (saját metódusaidat) vezetsz be a for-in ciklusokba, ami megszakíthatja a meglévő szkripteket. Néhány évvel ezelőtt a Prototype könyvtár szerzőinek újra kellett tervezniük a könyvtáruk implementációját, hogy eltávolítsák épp az ilyen típusú dolgokat.

Ha nem kell aggódnod a kompatibilitás miatt a weboldaladon futó más JavaScripttel, nyugodtan használd, különben inkább a kényelmetlenebb, de biztonságosabb önálló függvénymegoldást javaslom.

Válasz #10

Teljesítmény

Ma, 2020.01.07, teszteket végzek MacOs HighSierra 10.13.6 rendszeren a Chrome v78.0.0, Safari v13.0.4 és Firefox v71.0.0 böngészőkön 15 kiválasztott megoldásra. Következtetések

  • A JSON, Set és meglepő módon a find (K,N,O) alapú megoldások minden böngészőn a leglassabbak
  • Az ES6 includes (F) csak Chrome-on gyors
  • A for (C,D) és a indexOf (G,H) alapú megoldások minden böngészőn elég gyorsak kis és nagy tömbökön, így valószínűleg ezek a legjobb választás a hatékony megoldáshoz.
  • Azok a megoldások, ahol az index csökken a ciklus során, (B) valószínűleg lassabb, mert így működik a CPU gyorsítótára.
  • Én is futtattam tesztet nagy tömbre, amikor a keresett elem a tömb hosszának 66%-os pozíciójában volt, és a for-ra (C,D,E) alapuló megoldások hasonló eredményeket adtak (~630 művelet/mp - de az E Safari és Firefox alatt 10-20%-kal lassabb volt, mint a C és D).

Eredmények

Részletek

Két tesztesetet végzek: egy 10 elemű tömbre, és egy 1 millió elemű tömbre. Mindkét esetben a keresett elemet a tömb közepére helyezzük.

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!

Tömb kicsi - 10 elem

Itt végezhet teszteket a gépén

Tömb nagy - 1.000.000 elem

Itt végezhet teszteket a gépén

Válasz #11

Egy soros:

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

Válasz #12

Ha egy pillanatra kimozdulunk a megszokott gondolkodásmódból, ha ezt a hívást sok-sok alkalommal végzed, sokkal hatékonyabb egy asszociatív tömb Map használata a keresésekhez hash függvény segítségével.

https://developer.mozilla.org/hu/docs/Web/JavaScript/Reference/Global_Objects/Map

Válasz #13

Én a következőket használom:

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

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

a.contains('foo'); // true
a.contains('fox'); // false

Válasz #14

Van néhány módszer, ami megkönnyíti ennek az elérését (includes, some, find, 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.

Többet az include, some, find, findIndex-ről

Válasz #15

function contains(a, obj) {
    return a.some(function(element){return element == obj;})
}

Az Array.prototype.some() az ECMA-262 szabvány 5. kiadásában lett hozzáadva

Válasz #16

Ha JavaScript 1.6-ot vagy későbbit (Firefox 1.5-öt vagy későbbit) használsz, használhatod az Array.indexOf-t. Ellenkező esetben azt hiszem, valami hasonlóval fogsz végezni, mint az eredeti kódod.

Válasz #17

Remélhetőleg gyorsabb kétirányú indexOf/lastIndexOf alternatíva

2015

Bár az új includes módszer nagyon jó, a támogatás jelenleg gyakorlatilag nulla.

Már régóta gondolkodom egy módon, hogy helyettesítsem a lassú indexOf/lastIndexOf függvényeket.

A teljesítményorientált módszert már megtalálták, ha megnézzük a legjobb válaszokat. Ezek közül a @Damir Zekic által közzétett contains függvényt választottam, amelynek a leggyorsabbnak kell lennie. De azt is megemlíti, hogy a mérési eredmények 2008-ból származnak, így elavultak.

Én is a while-t részesítem előnyben a for-ral szemben, de nem konkrét okból a függvényt végül egy for ciklussal írtam meg. Ezt while ---val is meg lehetett volna csinálni.

Kíváncsi voltam, hogy az iteráció sokkal lassabb-e, ha egyszerre mindkét oldalát ellenőrzöm a tömbnek. Látszólag nem, így ez a funkció körülbelül kétszer gyorsabb, mint a legtöbb szavazatot kapottak. Nyilvánvalóan gyorsabb is, mint a natív verzió. Ez egy valós környezetben van, ahol sosem tudhatod előre, hogy a keresett érték a tömb elején vagy végén van-e.

Amikor tudod, hogy épp egy értéket tettél egy tömbbe, a lastIndexOf használata valószínűleg a legjobb megoldás marad, de ha nagy tömbökön kell áthaladnod és az eredmény bárhol lehet, ez egy szilárd megoldás lehet a dolgok gyorsabbá tételéhez.

Kétirányú 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');

Teljesítményteszt

https://jsbench.me/7el1b8dj80

Tesztként létrehoztam egy tömböt 100 ezer bejegyzéssel.

Három lekérdezés: a tömb elején, közepén és végén.

Remélem, te is érdekesnek találod ezt, és teszteled a teljesítményt.

Megjegyzés: Amint látjátok, kissé módosítottam a contains függvényt, hogy tükrözze a indexOf és lastIndexOf kimenetét (szóval gyakorlatilag true az index-szel és false a -1-gyel). Ez nem árt neki.

A tömb prototípus változata

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

A függvény könnyen módosítható úgy is, hogy true-t vagy false-t adjon vissza, vagy akár az objektumot, a stringet, vagy bármi mást.

És itt van a while változat:

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

Hogyan lehetséges ez?

Azt gondolom, hogy a visszavert index kiszámításának egyszerű módja egy tömbben olyan egyszerű, hogy kétszer olyan gyors, mint tényleges ciklusiterációt végezni.

Itt egy bonyolult példa, amely iterációnként három ellenőrzést végez, de ez csak hosszabb számítással lehetséges, ami a kód lassulását okozza.

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

Válasz #18

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

Visszaadja a tömb indexét, ha megtalálható, vagy -1-et, ha nem található

Válasz #19

Ha ismételten ellenőrzöd, hogy egy objektum létezik-e egy tömbben, érdemes lehet utánanézni

  1. A tömb folyamatos rendezésének fenntartása beszúró rendezés alkalmazásával a tömbben (helyezd az új objektumokat a megfelelő helyre)
  2. Az objektumok frissítését úgy készítse el, hogy az eltávolítás+rendezett beszúrás műveletként történjen és
  3. Használj bináris keresést a contains(a, obj) függvényedben.

Válasz #20

Ezt a kódmorzsát használjuk (működik objektumokkal, tömbökkel, karakterláncokkal):

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

Használat:

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

Válasz #21

Megoldás, amely minden modern böngészőben működik:

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

Használat :

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

IE6+ megoldás:

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

Használat :

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

Miért használjuk a JSON.stringify-t?

Array.indexOf és Array.includes (ahogy a legtöbb itt található válasz is) csak referenciák szerint hasonlítja össze, nem az értékük alapján.

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

Bónusz

Nem optimalizált ES6 egysoros:

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

Megjegyzés: Az objektumok érték szerinti összehasonlítása jobban működik, ha a kulcsok ugyanabban a sorrendben vannak, ezért biztonságosabb, ha először rendezed a kulcsokat egy ilyen csomag segítségével: https://www.npmjs.com/package/sort-keys

Frissítve lett a contains függvény egy teljesítményoptimalizálással. Köszönöm itinance-nak, hogy felhívta rá a figyelmet.

Válasz #22

Használd a lodash some függvényét.

Tömör, pontos, és nagyszerű többplatformos támogatással rendelkezik.

A elfogadott válasz még a követelményeknek sem felel meg.

Követelmények: Javasolja a legrövidebb és leghatékonyabb módját annak kiderítésére, hogy egy JavaScript tömb tartalmaz-e egy objektumot.

Elfogadott válasz:

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

Ajánlásom:

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

Megjegyzések :

$.inArray jól működik annak meghatározására, hogy egy skalár érték létezik-e egy skalárokból álló tömbben...

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

... de a kérdés egyértelműen egy hatékony módot kér arra, hogy meghatározzuk, hogy egy objektum szerepel-e egy tömbben.

Annak érdekében, hogy mind skalárokat, mind objektumokat kezelhess, ezt tehetnéd:

(_.isObject(item)) ? _.some(ary, item) : (_.indexOf(ary, item) > -1)

Válasz #23

Ennek a követelménynek az egyszerű megoldása a find() használata

Ha az alábbihoz hasonló objektumtömböd van,

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

Ezután ellenőrizheti, hogy a kívánt értékkel rendelkező objektum már jelen van-e vagy sem:

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

ha az adat null, akkor nincs admin, különben a meglévő objektumot adja vissza, például:

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

Ezután megtalálhatja annak az objektumnak a tömbbeli indexét, és kicserélheti az objektumot a kód használatával:

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

olyan értéket fogsz kapni, mint:

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

Válasz #24

Az ECMAScript 6-nak van egy elegáns javaslata a find-ra.

A find metódus egyszer végrehajtja a visszahívó függvényt minden olyan tömbbeli elemre, amíg meg nem talál egy olyat, ahol a visszahívó igaz értéket ad vissza. Ha ilyen elem található, a find azonnal visszaadja az adott elem értékét. Ellenkező esetben a find undefined értéket ad vissza. A visszahívó függvényt csak a tömb azon indexein hívják meg, amelyekhez érték van rendelve; nem hívják meg azokat az indexeket, amelyeket töröltek, vagy amelyekhez soha nem rendeltek értéket.

Itt van az erről szóló MDN dokumentáció.

A keresési funkció így működik.

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

Ezt az ECMAScript 5-ben és az alatt úgy használhatja, hogy definiálja a függvényt.

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

Válasz #25

Bár a array.indexOf(x)!=-1 a legkonkrétabb módja ennek (és több mint egy évtizede nem-Internet Explorer böngészők is támogatják...), ez nem O(1), hanem O(N), ami szörnyű. Ha a tömböd nem fog változni, átalakíthatod a tömböt egy hash-táblává, majd használhatod a table[x]!==undefined vagy ===undefined kifejezéseket:

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

Demó :

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

(Sajnos, bár létrehozhatsz egy Array.prototype.contains-t, hogy "befagyaszd" a tömböt és két sorban tárolj egy hashtáblát a this._cache-ben, ez rossz eredményekhez vezetne, ha később szerkesztenéd a tömbödet. A JavaScript-nek nincsenek elegendő horgonyai arra, hogy ezt az állapotot megtartsa, ellentétben például a Python-nal.)

Válasz #26

Használhatunk egy Set-et, amely rendelkezik a "has()" metódussal:

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

Kapcsolódó cikkek