webdevqa.jp.net

配列にJavaScriptのオブジェクトが含まれているかどうかを確認する方法

JavaScriptの配列にオブジェクトが含まれているかどうかを確認するための最も簡潔で効率的な方法は何ですか?

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

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

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

これはスタックオーバーフローの質問と非常に密接に関連しています。JavaScriptの配列で項目を見つけるための最良の方法?indexOfを使用して配列内のオブジェクトを見つける方法を示します。

3563
brad

現在のブラウザには Array#includes があり、 正確に それ、 は広くサポートされている 、および polyfill は古いブラウザ用です。

> ['joe', 'jane', 'mary'].includes('jane');
true 

Array#indexOf を使用することもできますが、これは直接的ではありませんが、古くなったブラウザにはPolyfillsを必要としません。

jQueryは $.inArray を提供しています。これは機能的にArray#indexOfと同等です。

underscore.js (JavaScriptユーティリティライブラリ)は _.contains(list, value) 、alias _.include(list, value)を提供します。どちらもJavaScript配列を渡す場合は内部で indexOf を使用します。

他のいくつかのフレームワークも同様の方法を提供します。

いくつかのフレームワークはこれを関数として実装していますが、他のフレームワークは配列プロトタイプに関数を追加しています。

3894
codeape

更新:@oripがコメントで述べたように、リンクされたベンチマークは2008年に行われたので、結果は現代のブラウザには関係ないかもしれません。しかし、とにかくモダンではないブラウザをサポートするためにこれが必要になるかもしれません、そして、おそらくそれらはそれ以来更新されていません。常に自分自身をテストしてください。

他の人が言っているように、配列を介した繰り返しはおそらく最善の方法ですが、 証明されました 減少する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
374
Damir Zekić

indexOf 多分、それは「ECMA-262標準に対するJavaScriptの拡張であり、標準の他の実装には存在しないかもしれない」

例:

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

AFAICS Microsoftは not を使用して何らかの代替手段を提供しています これにはInternet Explorer(およびindexOfをサポートしていない他のブラウザ)の配列に同様の機能を追加できます。 Googleで簡単に検索すると (たとえば、 これ )と表示されます。

169
cic

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とは異なり、includesSameValueZero equalityアルゴリズムを使用して比較します。つまり、配列にNaNが含まれているかどうかを検出できます。

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

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

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

現在はまだドラフトですが、 polyfilled にすることですべてのブラウザで動作させることができます。

140
Oriol

bは値、aは配列です。 trueまたはfalseを返します。

function(a, b) {
    return a.indexOf(b) != -1
}
100
william malo

これが 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;
        };
}
71
Már Örlygsson

一番上の答えはプリミティブ型を想定していますが、配列に何らかの特性を持つオブジェクトが含まれているかどうかを調べたい場合は、 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サポート表

66
Michael

つかいます:

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

// Usage
if(isInArray(my_array, "my_value"))
{
    //...
}
50
Matías Cánepa

JavaScriptのArrayオブジェクトを拡張することは、既存のスクリプトを壊す可能性があるfor-inループに新しいプロパティ(カスタムメソッド)を導入するため、本当に悪い考えです。数年前、 Prototype ライブラリの作者は、このようなことを取り除くためにライブラリの実装を作り直す必要がありました。

あなたのページで走っている他のJavaScriptとの互換性について心配する必要がないなら、それを試してください。

42
Mason Houtz

箱から出してすぐに考えて、何度もこの電話をかける場合は、使用する方がはるかに効率的です。 連想配列 ハッシュ関数を使って検索するMap.

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

27
MattMcKnight

ワンライナー:

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

私は以下を使います:

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

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

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

Array.prototype.some() は、第5版でECMA-262規格に追加されました。

19
dansalmo

うまくいけばもっと速い双方向のindexOf/lastIndexOfの選択肢

2015年

新しいメソッド includes はとてもいいですが、今のところサポートは基本的にゼロです。

遅いindexOf/lastIndexOf関数を置き換える方法を考えていたのは、長い間です。

トップの答えを見て、パフォーマンス的な方法はすでに見つかっています。それらの中から@Damir Zekicが投稿したcontains関数を選びました。しかしそれはまたベンチマークが2008年からのものであり、時代遅れであるとも述べています。

私はまたwhileよりforを好みます、しかし、特定の理由のために私は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つのクエリ:最初に、中央に、そして配列の最後に。

私はあなたもこれが面白いと思うとパフォーマンスをテストすることを願っています。

注:ご覧のように、indexOfとlastIndexOfの出力を反映するようにcontains関数を少し変更しました(したがって、基本的にtrueindex、および-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');

この関数は、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

14
cocco

もしあなたが配列内のオブジェクトの存在を繰り返しチェックしているのであれば、あなたは多分調べるべきです

  1. 配列内で 挿入ソート を実行して常に配列をソートしておく(新しいオブジェクトを正しい場所に配置する) 
  2. 更新オブジェクトを削除+ソート挿入操作として作成し、
  3. あなたのcontains(a, obj)binary search lookupを使ってください。
12
Ztyx

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

/*
 * @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
12
dr.dimitru
function inArray(elem,array)
{
    var len = array.length;
    for(var i = 0 ; i < len;i++)
    {
        if(array[i] == elem){return i;}
    }
    return -1;
} 

見つかった場合は配列インデックス、見つからなかった場合は-1

12
LmC

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

10
Andru Luvisi

Lodashの some 関数を使用してください。

それは簡潔で正確で、素晴らしいクロスプラットフォームサポートを持っています。

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

Requirements: JavaScriptの配列にオブジェクトが含まれているかどうかを調べる最も簡潔で効率的な方法をお勧めします。

利用可能な回答:

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

私のおすすめ:

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

ノート: 

$ .inArrayはスカラー値がスカラーの配列に存在するかどうかを判断するのに問題なく動作します...

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

...しかし、質問はobjectが配列に含まれているかどうかを判断するための効率的な方法を明確に求めています。

スカラーとオブジェクトの両方を処理するために、これを行うことができます。

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

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

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

9
Igor Barbashin

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を作成して2行でthis._cacheに "フリーズ"してハッシュテーブルを格納することはできますが、後で配列を編集することを選択した場合、これは間違った結果になります。たとえばPythonとは異なり、この状態を維持しましょう。)

8
ninjagecko

ECMAScript 6には、findに関する優雅な提案があります。

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

これが 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;
    }
  });
}
7
Pradeep Mahdevu

つかいます:

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

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

デモ

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

6
Mina Gabriel

これが プロトタイプのやり方です

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

接続方法については here も参照してください。

4
Ken

このトリックを使うこともできます。

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

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

つかいます:

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方法がないため、これは配列内の2つのエンティティを比較するのと同じくらい近いと思います。また、Arrayオブジェクトを拡張するのは賢明なことではないかもしれませんが、場合によってはそれで問題ありません(あなたがそれとトレードオフを知っていれば)。

3
Carlos A

メソッド "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'));
3
rlib
  1. Array.indexOf(Object)を使用してください。 
  2. ECMA 7では、Array.includes(Object)を使うことができます。 
  3. ECMA 6では、Array.find(FunctionName)を使用できます。ここでFunctionNameは、配列内のオブジェクトを検索するためのユーザー定義関数です。

    お役に立てれば!

2
kg11

他の人が言ったようにあなたはArray.indexOfを使うことができます、しかしそれはすべてのブラウザで利用可能ではありません。これは https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf からのコードです。古いブラウザでも同じように機能します。

indexOfは、最近ECMA-262標準に追加されました。そのため、すべてのブラウザに存在するわけではありません。これを回避するには、スクリプトの先頭に次のコードを挿入して、ネイティブにサポートされていない実装では indexOfを使用します。このアルゴリズムは、Object、TypeError、Number、Math.floor、Math.abs、およびMath.max を前提として、ECMA-262の第5版で指定されたものとまったく同じです。彼らの元の価値。

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

この質問にはまだ最新の構文が追加されておらず、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 - >(コールバックを取り、最初の値を返す value/object 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を返す最初の値/オブジェクトの index を返す)。

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条件を創造的に設定することによって、配列から(参照がない場合でも)任意のオブジェクトを取得できます。

2
Sumer

決して最高というわけではありませんが、私はクリエイティブになってレパートリーを増やしただけでした。

これを使わないで

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

2
sqram

私は提出された答えを調べ、それらが参照によってオブジェクトを検索した場合にのみ適用されることを得ました。参照対象比較を用いた簡単な線形探索 

しかし、あなたがオブジェクトへの参照を持っていないとしましょう、あなたはどうやって配列の中の正しいオブジェクトを見つけるのでしょうか?各オブジェクトと比較しながら、直線的に深く比較する必要があります。リストが大きすぎ、その中のオブジェクトが大きなテキストを含む非常に大きい場合を想像してください。配列内の要素の数とサイズによってパフォーマンスが大幅に低下します。

オブジェクトを文字列化してネイティブハッシュテーブルに入れることができますが、これらのキーが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));
1
stamat

ES6を使用している場合セットを使用できます。

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

これは、他の方法よりもパフォーマンスが優れているはずです。

1
Neil Girardi

またはこの解決策:

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

同様のこと: "search 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)]
1
Andy Rohr

私はすべての重複値を削除して新しいリストを返す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;
}
1
Jeeva

アンダースコアライブラリは値を返し、すべてのブラウザでサポートされているため、アンダースコアライブラリの使用をお勧めします。 

アンダースコア

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

1つのパラメータがあります。オブジェクトの配列番号です。配列内の各オブジェクトには、xとyで表される2つの整数プロパティがあります。関数は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 } ];
    count = 0; 
var n = numbers.length;
for (var i =0;i<n;i++)
{
  if(numbers[i].x==numbers[i].y)
  {count+=1;}
}

alert(count);
1
Mitul Panchal

IdnexOf()を使用することは良い解決策ですが、〜演算子で-1を返す組み込み実装indexOf()関数を隠すべきです: 

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

他の人が言ったことに加えて、配列内で検索したいオブジェクトの参照がない場合は、次のようにすることができます。

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を返します。

0
Nitesh Ranjan

JavaScriptインビルド関数を含む使用

var optval = [];

optval.Push('A');    
optval.Push('B');    
optval.Push('C');

Javascript配列で文字列Aを次のように検索できます。

optval.includes('A') // =====> return true
0
Rajeev Ranjan

簡単な解決策:ES6の機能 " includes "メソッド

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

  arr.includes(2) // true

  arr.includes(93) // false
0
ngCourse
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);
0
Sanjay Magar