JavaScriptで配列に値が含まれているかどうかを確認するにはどうすればよいですか?


3997

JavaScript配列に値が含まれているかどうかを確認する最も簡潔で効率的な方法は何ですか?

これが私が知っている唯一の方法です。

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

これを達成するためのより良い、より簡潔な方法はありますか?

これは、スタックオーバーフローの質問と非常に密接に関連しています。これは、を使用して配列内のオブジェクトを見つけることを扱いますindexOf


49
ちょうどテストされました:あなたの方法は実際にブラウザー全体で最も高速です:jsOff.com/find-element-in-obj-vs-array/2(変数にa.lengthを事前に保存することは別として) .inArrayは)はるかに遅い
ジョーンBerkefeld

17
ここではArray#indexOfが最良の選択であると多くの人が答えました。しかし、ブール値に正しくキャストできるものが必要な場合は、これを使用します。false ~[1,2,3].indexOf(4)と評価される0を~[1,2,3].indexOf(3)返し、trueと評価される-3を返します。
lordvlad 2013年

8
~必要なため、ブール値に変換するために使用するものではありません!。ただし、この場合、-1と等しいかどうかを確認する必要があるため、関数はreturn [1,2,3].indexOf(3) === -1; ~バイナリではなく終了する可能性があり、値の各ビットを個別に反転します。
mcfedr 2014年

14
@Iordvlad [1,2,3].indexOf(4)は実際には-1を返します。@mcfedrが指摘したように~ビット単位のNOT演算子です。ES511.4.8を参照してください。ことは、のバイナリ表現は-11のみで構成0されるため、その補数はであり、falseと評価されます。他の数値の補数はゼロではないため、真になります。したがって、~正常に動作し、と組み合わせて使用​​されることがよくありindexOfます。
mknecht 2015年

5
タイトルは誤解を招くものです。どこ[[1,2],[3,4]].includes([3,4])
mplungjan 2017

回答:


4378

最新のブラウザにはがありArray#includes、これはまさにそれを行い、IEを除くすべての人が広くサポートしています。

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

Array#indexOf直接的ではないが、古いブラウザではポリフィルを必要としないを使用することもできます。


多くのフレームワークでも同様のメソッドが提供されています。

一部のフレームワークはこれを関数として実装し、他のフレームワークはその関数を配列プロトタイプに追加することに注意してください。


42
MooToolsにはブール値を返すArray.containsもあり、これは本当の質問のように聞こえます。
ライアンフローレンス

22
プロトタイプもArray.includeブール値を返します
user102008

46
優れたブラウザを使用している場合は、そのまま使用できますarray.indexOf(object) != -1
Sam Soffes

13
また、最初の要素が0を返し、偽物として評価されるため、indexOfだけを条件として使用しないでください。
プラス

241
inArray要素のインデックスを返す関数のひどい名前であり、-1存在しない場合。ブール値が返されることを期待します。
Tim

434

2019からの更新:この回答は2008(11歳!)からのものであり、最新のJSの使用には関係ありません。約束されたパフォーマンスの改善は、当時のブラウザで行われたベンチマークに基づいていました。最近のJS実行コンテキストには関係ないかもしれません。簡単な解決策が必要な場合は、他の答えを探してください。最高のパフォーマンスが必要な場合は、関連する実行環境でベンチマークを行ってください。

他の人が言ったように、配列を介した反復がおそらく最良の方法ですが、減少するループがJavaScriptで反復する最も速い方法であることが証明されていwhileます。したがって、次のようにコードを書き直すことをお勧めします。

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


22
「証明された」は強い言葉です。JSエンジンは常に改善されており、3年前に測定された実行時間はひどく時代遅れです。
orip

2
@Damir-同意する。おそらく、可能であればindexOfを使用するようにサンプルを変更し、このコードを盲目的にコピーアンドペーストすると、最高のパフォーマンスが得られます。
orip

1
@cbmeeksええ、確かに注意が必要です。これはおそらく、for (o in array)一般的にアレイをループするときに行うべきではないケースでした...
DamirZekić12年

1
これを行う最良の方法は、[1、2、3] .indexOf(1)> -1かどうかをチェックすることです
Devin G Rhode

207

indexOf 多分、それは「ECMA-262標準へのJavaScript拡張です。そのため、標準の他の実装には存在しない可能性があります」。

例:

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

AFAICS Microsoftはこれに対する何らかの代替手段提供していませindexOf、必要に応じて、Googleクイック検索で明らかになるように(たとえば、これをサポートしていない他のブラウザー)の配列に同様の機能を追加できます(この例など))。


実際に、リンクしたdeveloper.mozilla.orgページに、それをサポートしていないブラウザー用のindexOf拡張の実装の例があります。
ロイドコテン

実際には、indexofをサポートしていないブラウザー(IE7など)の配列のプロトタイプにindexofを追加すると、配列内のアイテムをループするときにこの関数もループしようとします。不快な。
CpILL


オブジェクトのチェックに適用できますか?オブジェクトの場合は機能しないと思います
Himesh Aadeshara、2018年

169

ECMAScript 7が導入 Array.prototype.includesます。

次のように使用できます。

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

また、オプションの2番目の引数も受け入れますfromIndex

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

違ってindexOf使用する、厳密な等価比較をincludes使用して比較しSameValueZero平等アルゴリズムを。つまり、配列にNaN:が含まれているかどうかを検出できます。

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

また、とは異なりindexOfincludes欠落しているインデックスをスキップしません。

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

現在はまだ下書きですが、すべてのブラウザで機能するようにポリフィルすることができます。


3
IEとMicrosfotエッジ(2015)(のためにサポートされていませんdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
アドリアーノレゼンデ


オブジェクトのチェックに適用できますか?オブジェクトの場合は機能しないと思います
Himesh Aadeshara、2018年

128

上位の回答はプリミティブ型を想定していますが、配列にある特性を持つオブジェクトが含まれているかどうかを確認する場合、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
}

*コメントで指摘したように、この回答の時点では、2018年9月Array.prototype.some()が完全にサポートされています。caniuse.comサポートテーブル


1
2018年9月現在、Array.prototype.some()は完全にサポートされています。caniuse.comサポートテーブル
jamess

1
AWS Node.js Lambdaのノード> = 8.10で作業しているので、これは素晴らしいことです。非常にクリーンでシンプルなソリューション!👍🏻–
ジョーダン

1
@jamess十分にサポートされている可能性がありますがArrow functions、この例では十分にサポートされていないことに注意してください。:詳細はこちらをご覧くださいdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
カミル・ウィコウスキー

短絡はありますか?それとも、値が見つかった場合でも、配列全体を反復しますか?
Douglas Gaskell

@DouglasGaskellは、見つかった反復を中止します(回答で述べられています)
Michael

112

次のように配列を定義したとしましょう:

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

以下に3つの方法があるかどうかを確認します3。それらのすべてがまたはのいずれtrueかを返しますfalse

ネイティブ配列メソッド(ES2016以降)(互換性テーブル

array.includes(3) // true

カスタム配列メソッドとして(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

"b"が配列 "a"にある場合はtrueを返します...それを説明する他の方法がわかりません...
william malo

4
この部分はわかりません「!!〜」。IE8はArrayオブジェクトのindexOf()をサポートしていないため、これはIE8では機能しないと思います。
svlada

62
「〜」は、数値から1をフロアリング、反転、および減算する演算子です。indexOfは、失敗すると-1を返すため、「〜」は-1を「0」に変換します。「!!」を使用 数値をブール値に変換します(!! 0 === false)
malo

1
かっこいいですが、単純にするために真剣に書きます。a.indexOf(b)>-1だけではありません。 ">-1" .length === "!!〜" .length
super

2
ブール演算子の影響についての知識の欠如は専門家ではないと思います。しかし、私は可読コードの価値について同意します。これを明確にラベル付けされた関数で確実にラップします。そして、まさにそれがほとんどの主要なJSフレームワークが行うことです。
okdewit

79

以下は、JavaScript 1.6互換の実装です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;
        };
}

これは素晴らしいように見えますが、少し混乱しています:* 1行目と3行目のテストは同等ではありませんか?*プロトタイプをテストし、必要に応じてArray.prototypeに関数を追加した方がよいのではないでしょうか。
Avi Flax 2010

10
彼らは平等ではありません。[].indexOfの省略形ですArray.prototype.indexOf。私たちパラノイア防御的なJavascriptプログラマーは、ネイティブプロトタイプの拡張を一切犠牲にしません。
MARÖrlygsson

1
されていない[].indexOf新しい配列を作成し、アクセスしindexOfながら、Array.prototype.indexOfちょうど直接プロトタイプをアクセスしますか?
アレックス

3
@alexはい[].indexOf === Array.prototype.indexOf(FireBugで試してみてください)、逆に[].indexOf !== Array.indexOf
MARÖrlygsson

57

使用する:

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

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

25
x ? true : false通常は冗長です。ここです。
Ry-

@minitechなぜ冗長だと言うのですか?
マティアスCánepa

8
array.indexOf(search) >= 0はすでにブール値です。ただreturn array.indexOf(search) >= 0
Ry-

@minitechよろしくお願いします!実際に、そのような構造物が返されることを知りませんでした。TIL何か新しいもの。
マティアスCánepa

文字通り、JavaScriptの任意の構成要素を返すことができます
BT

49

JavaScript Arrayオブジェクトを拡張することは、for-in既存のスクリプトを破壊する可能性のあるループに新しいプロパティ(カスタムメソッド)を導入するため、非常に悪い考えです。数年前、Prototypeライブラリの作成者は、この種のものだけを削除するために、ライブラリ実装を再設計する必要がありました。

ページ上で実行されている他のJavaScriptとの互換性について心配する必要がない場合は、それを検討してください。そうでない場合は、より厄介ですが安全な独立した関数ソリューションをお勧めします。


22
同意しません。まさにこの理由から、for-inループを配列に使用しないでください。人気のjsライブラリの1つを使用すると、for-inループを使用すると機能しなくなります
Tomas

これはサルのパッチと見なされますか?笑そのような人もいます。
cbmeeks 2012年

33

一発ギャグ:

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

8
array.filter(e=>e==x).length > 0同じですarray.some(e=>e==x)が、someより効率的である
アポロ


28

私は以下を使用します:

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

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

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


19

うまくいけば、より高速な双方向indexOf/ lastIndexOf代替

2015年

新しい方法には非常に優れていますが、現時点ではサポートは基本的にゼロです。

遅いindexOf / lastIndexOf関数を置き換える方法を考えていたのは久しぶりです。

上位の回答を見て、パフォーマンスの高い方法がすでに見つかりました。それらから私が選んだcontains、@ Damir Zekicが投稿し関数の中で最速の。しかし、それはまた、ベンチマークが2008年からのものであり、そのため古くなっているとも述べています。

私もを好みますwhilefor、特定の理由ではなく、forループを使用して関数の記述を終了しました。それは、while --

実行中に配列の両側をチェックすると、反復がはるかに遅くなるのではないかと気になりました。どうやらそうではないので、この関数は上位投票の関数より約2倍高速です。もちろん、ネイティブよりも高速です。これは、検索している値が配列の先頭にあるのか末尾にあるのかがわからない、現実の環境におけるものです。

値を持つ配列をプッシュしたことがわかっている場合は、おそらく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');

性能試験

http://jsperf.com/bidirectionalindexof

テストとして、100kエントリの配列を作成しました。

3つのクエリ:配列の最初、中央、最後。

これも面白いと思い、パフォーマンスをテストしてください。

注:ご覧のとおりcontains、indexOfおよびlastIndexOfの出力を反映するように関数を少し変更しました(trueつまりindex、基本的にとfalse-1)。それはそれを害するべきではありません。

配列プロトタイプバリアント

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

この関数は、trueまたはfalseを返すように簡単に変更したり、オブジェクト、文字列、またはそれが何であっても返すことができます。

そしてここに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');

これはどのようにして可能ですか?

配列に反映されたインデックスを取得する単純な計算は非常に単純で、実際のループ反復を実行するよりも2倍速いと思います。

以下は、反復ごとに3つのチェックを行う複雑な例ですが、これはコードの速度低下を引き起こすより長い計算でのみ可能です。

http://jsperf.com/bidirectionalindexof/2


18

パフォーマンス

今日2020.01.07私は、選択した15のソリューションについて、Chrome v78.0.0、Safari v13.0.4、Firefox v71.0.0のMacOs HighSierra 10.13.6でテストを実行します。結論

  • に基づくソリューションJSONSetそして驚くべきことにfind(K、N、O)はすべてのブラウザーで最も遅い
  • es6 includes(F)はChromeでのみ高速です
  • 基づくソリューションfor(C、D)とindexOf(G、H)には、大小のアレイのすべてのブラウザーで非常に高速であるため、おそらく効率的なソリューションに最適です
  • ループ中にインデックスが減少するソリューション(B)は、CPUキャッシュが機能するためか、おそらく遅くなります。
  • また、検索された要素が配列の長さの66%の位置にあるときに大きな配列のテストを実行し、 for(C、D、E)には同様の結果が得られます(〜630 ops /秒-サファリとファイアフォックスのEは10でした) CおよびDより20%遅い)

結果

ここに画像の説明を入力してください

詳細

2つのテストケースを実行します。10要素の配列と100万要素の配列の場合です。どちらの場合も、検索された要素を配列中央に配置します。

小配列-10要素

ここでマシンでテストを実行できます

ここに画像の説明を入力してください

大きな配列-1.000.000要素

ここでマシンでテストを実行できます

ここに画像の説明を入力してください


16

JavaScript 1.6以降(Firefox 1.5以降)を使用している場合は、Array.indexOfを使用できます。そうでなければ、私はあなたがあなたの元のコードに似たものになるだろうと思います。


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

見つかった場合は配列のインデックスを返し、見つからない場合は-1を返します


16

このスニペットを使用します(オブジェクト、配列、文​​字列で動作します):

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

15

配列内のオブジェクトの存在を繰り返しチェックしている場合は、おそらく調査する必要があります

  1. 配列で挿入ソートを実行して、常に配列をソートしたままにします(新しいオブジェクトを適切な場所に配置します)。
  2. 削除+ソートされた挿入操作として更新オブジェクトを作成し、
  3. バイナリ検索ルックアップを使用しますcontains(a, obj)

2
または、可能であれば、MattMcKnightとninjageckoが示唆しているように、配列の使用を完全に停止し、代わりにオブジェクトを辞書として使用します。
joeytwiddle

13

最新のすべてのブラウザで機能するソリューション:

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.indexOfそしてArray.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


containsperf最適化で関数を更新しました。おかげitinanceそれを指摘して。


この特定のコードチャンクはIE6で動作する可能性がありますが(テストされていません)、IEはIE9までES5をサポートしていませんでした。
マークリード

パフォーマンス上の理由から、文字列化は避けてください。少なくともすべてのループで「obj」をJSON.stringifyすることは避けてください。コストが高く、アプリケーションの速度が低下するためです。そのため、一時変数でforループの前にキャプチャする必要があります
巡回

1
@itinance良い点。includesあなたの提案で機能を更新しました。私は自分の関数でjsperfを実行しました。lodashのインクルードよりも約5倍遅くなります。lodashは値で比較しないと見つけることができませんけれども{a: 1}の中で[{a: 1}]。どのライブラリがそれを行うかはわかりません。しかし、これ以上パフォーマンスが高く、めちゃくちゃ複雑な方法ではないかどうか知りたいです。
Igor Barbashin 2017

後期注意:contains([{ a: 1, b: 2 }], { b: 2, a: 1 })文字列化されたオブジェクトはプロパティの順序を維持するため、これはたとえば、動作しません。
異教の猿

1
@HereticMonkey、本当です。そのためsort-keys、下部にメモを追加しました
Igor Barbashin

12

ロダッシュのいくつかを使用してください関数をます。

簡潔かつ正確で、優れたクロスプラットフォームサポートを備えています。

受け入れられた回答は要件を満たしていません。

要件: 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)

10

ECMAScript 6には、findに関するエレガントな提案があります。

findメソッドは、コールバックがtrueの値を返す要素を見つけるまで、配列に存在する各要素に対してコールバック関数を1回実行します。そのような要素が見つかった場合、findはすぐにその要素の値を返します。それ以外の場合、findは未定義を返します。コールバックは、値が割り当てられている配列のインデックスに対してのみ呼び出されます。削除されたインデックス、または値が割り当てられていないインデックスに対しては呼び出されません。

これに関する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;
    }
  });
}


9

一方でarray.indexOf(x)!=-1これを行うには、最も簡潔な方法です(と... 10年以上にわたって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に2行で格納できますが、後で配列を編集することを選択した場合、これは誤った結果をもたらします。JavaScriptには十分なフックがありませんたとえばPythonとは異なり、この状態を維持できます。)


9

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


5
return proxy.has(obj)ここにif-elseステートメントがある2行よりもずっときれいだと思います
Maciej Bukowski

function contains(arr, obj) { return new Set(arr).has(obj); }
Gordon Bean

8

使用する:

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

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

デモ

tilde ~この時点での動作を正確に知るには、この質問を参照してください。チルドが式の前にある場合、チルドは何をしますか?


5
これはすでに1年半前に投稿されており、繰り返す必要はありません。
シャドウウィザードは

3
実際には投稿されていません。答えとしてではなく、答えに対するコメントとして、そしてそれでも明確で簡潔ではありません。投稿してくれてありがとう、ミナ・ガブリエル。
T.CK 2018年

6

OK、コードを最適化して結果を得ることができます

これを行うには、よりクリーンで優れた多くの方法がありますが、私はあなたのパターンを取得してを使用してそれに適用したかったのですが、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;
}

後期注意:contains([{ a: 1, b: 2 }], { b: 2, a: 1 })文字列化されたオブジェクトはプロパティの順序を維持するため、これはたとえば、動作しません。
異端の猿

5

決して最高というわけではありませんが、私は独創的になり、レパートリーに追加するだけでした。

これを使用しないでください

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


これでない場合、何を使用する必要がありますか?
bryc 2017

@brycは、おそらく受け入れられたソリューション、またはここからの別のソリューションです。パフォーマンスをあまり気にしない場合は、これを使用できます
sqram

5

この質問にはまだ最新の構文が追加されておらず、私の2セントが追加されていることに驚いています。

オブジェクトの配列arrObjがあり、その中でobjを検索するとします。

Array.prototype。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

Array.prototype。含む ->(trueまたは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.prototype。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

Array.prototype。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はコールバックを取るので、真の条件を独創的に設定することにより、配列から任意のオブジェクト(参照がない場合でも)をフェッチできます。


5

この要件の簡単な解決策は、 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');

データがnullの場合は管理者がいません。それ以外の場合は、以下のような既存のオブジェクトを返します。

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

これが誰にも役立つことを願っています。


5

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.