アイテムがJavaScript配列にあるかどうかを確認する最良の方法は? [複製]
-
02-07-2019 - |
質問
この質問にはすでに回答があります:
オブジェクトが配列内にあるかどうかを調べる最良の方法は何ですか?
これは私が知っている最良の方法です:
function include(arr, obj) {
for(var i=0; i<arr.length; i++) {
if (arr[i] == obj) return true;
}
}
include([1,2,3,4], 3); // true
include([1,2,3,4], 6); // undefined
解決
ECMAScript 2016以降、 < code> includes()
arr.includes(obj);
IEまたはその他の古いブラウザーをサポートする場合:
function include(arr,obj) {
return (arr.indexOf(obj) != -1);
}
編集: ただし、これはIE6、7または8では機能しません。最善の回避策は、存在しない場合は自分で定義することです:
-
Mozillaの(ECMA-262)バージョン:
if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(searchElement /*, fromIndex */) { "use strict"; if (this === void 0 || 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 > 0) { n = Number(arguments[1]); if (n !== n) n = 0; else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) 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; }; }
-
ダニエル・ジェームスのバージョン:
if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (obj, fromIndex) { if (fromIndex == null) { fromIndex = 0; } else if (fromIndex < 0) { fromIndex = Math.max(0, this.length + fromIndex); } for (var i = fromIndex, j = this.length; i < j; i++) { if (this[i] === obj) return i; } return -1; }; }
-
roosteronacid のバージョン:
Array.prototype.hasObject = ( !Array.indexOf ? function (o) { var l = this.length + 1; while (l -= 1) { if (this[l - 1] === o) { return true; } } return false; } : function (o) { return (this.indexOf(o) !== -1); } );
他のヒント
jQueryを使用している場合:
$.inArray(5 + 5, [ "8", "9", "10", 10 + "" ]);
最初に、まだ持っていないブラウザのJavaScriptで indexOf
を実装します。たとえば、 Erik Arvidssonの配列エキストラ(また、関連するブログ投稿)。そして、ブラウザのサポートを気にせずに indexOf
を使用できます。以下に、彼の indexOf
実装のわずかに最適化されたバージョンを示します。
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (obj, fromIndex) {
if (fromIndex == null) {
fromIndex = 0;
} else if (fromIndex < 0) {
fromIndex = Math.max(0, this.length + fromIndex);
}
for (var i = fromIndex, j = this.length; i < j; i++) {
if (this[i] === obj)
return i;
}
return -1;
};
}
長さを保存するように変更され、反復ごとに検索する必要がなくなりました。しかし、違いはそれほど大きくありません。汎用性の低い関数の方が高速かもしれません:
var include = Array.prototype.indexOf ?
function(arr, obj) { return arr.indexOf(obj) !== -1; } :
function(arr, obj) {
for(var i = -1, j = arr.length; ++i < j;)
if(arr[i] === obj) return true;
return false;
};
標準関数を使用し、本当に必要なときのためにこの種のマイクロ最適化を残すことを好みます。しかし、マイクロ最適化に熱心な場合は、ベンチマークコメントでリンクされているroosterononacid、配列内のベンチマーク検索。しかし、それらはかなり粗雑です。完全な調査では、さまざまなタイプ、さまざまな長さのアレイをテストし、さまざまな場所で発生するオブジェクトを見つけます。
配列が並べ替えられていない場合、本当に良い方法はありません(上記のindexOfを使用することは別として、同じことだと思います)。配列がソートされている場合、バイナリ検索を実行できます。これは次のように機能します。
- 配列の中央の要素を選択します。
- 探している要素は、選択した要素よりも大きいですか?その場合、配列の下半分を削除しました。そうでない場合は、上半分を削除しました。
- 配列の残り半分の中央の要素を選択し、手順2のように残りの配列の半分を削除します。最終的には、要素を見つけるか、配列を調べる必要がなくなります。
バイナリ検索は、配列の長さの対数に比例した時間で実行されるため、個々の要素を調べるよりもはるかに高速です。
[] .has(obj)
.indexOf()
が実装されていると仮定する
Object.defineProperty( Array.prototype,'has',
{
value:function(o, flag){
if (flag === undefined) {
return this.indexOf(o) !== -1;
} else { // only for raw js object
for(var v in this) {
if( JSON.stringify(this[v]) === JSON.stringify(o)) return true;
}
return false;
},
// writable:false,
// enumerable:false
})
!!! Array.prototype.has = function(){...
を作成しないでください。すべての配列に列挙可能な要素が追加され、jsが破損するためです。
//use like
[22 ,'a', {prop:'x'}].has(12) // false
["a","b"].has("a") // true
[1,{a:1}].has({a:1},1) // true
[1,{a:1}].has({a:1}) // false
2番目の引数(フラグ)を使用すると、参照ではなく値による比較が強制されます
生オブジェクトの比較
[o1].has(o2,true) // true if every level value is same
目的によって異なります。 Web用にプログラミングする場合は、 indexOf
を避け、Internet&nbsp; Explorer&nbsp; 6でサポートされていない(それらの多くはまだ使用されています!)か、条件付きで使用します:
if (yourArray.indexOf !== undefined) result = yourArray.indexOf(target);
else result = customSlowerSearch(yourArray, target);
indexOf
はおそらくネイティブコードでコーディングされているため、JavaScriptで実行できるものよりも高速です(配列が適切な場合、バイナリ検索/二分法を除く)。
注:これは好みの問題ですが、ルーチンの最後に return false;
を実行して、真のブール値を返します...
ここにメタ知識がいくつかあります-Arrayで何ができるか知りたい場合は、ドキュメントを確認してください-MozillaのArrayページはこちら
https://developer.mozilla.org/en -US / docs / JavaScript / Reference / Global_Objects / Array
Javascript 1.6で追加されたindexOfへの参照が表示されます
オブジェクトがjavascriptの配列であるかどうかを確認する堅牢な方法の詳細は次のとおりです。
xa.js フレームワークの2つの関数を utils = {}に追加します
&#8216;コンテナ&#8217;これらは、配列を適切に検出するのに役立ちます。
var utils = {};
/**
* utils.isArray
*
* Best guess if object is an array.
*/
utils.isArray = function(obj) {
// do an instanceof check first
if (obj instanceof Array) {
return true;
}
// then check for obvious falses
if (typeof obj !== 'object') {
return false;
}
if (utils.type(obj) === 'array') {
return true;
}
return false;
};
/**
* utils.type
*
* Attempt to ascertain actual object type.
*/
utils.type = function(obj) {
if (obj === null || typeof obj === 'undefined') {
return String (obj);
}
return Object.prototype.toString.call(obj)
.replace(/\[object ([a-zA-Z]+)\]/, '$1').toLowerCase();
};
オブジェクトが配列内にあるかどうかを確認する場合は、次のコードも含めます。
/**
* Adding hasOwnProperty method if needed.
*/
if (typeof Object.prototype.hasOwnProperty !== 'function') {
Object.prototype.hasOwnProperty = function (prop) {
var type = utils.type(this);
type = type.charAt(0).toUpperCase() + type.substr(1);
return this[prop] !== undefined
&& this[prop] !== window[type].prototype[prop];
};
}
そして最後に、このin_array関数:
function in_array (needle, haystack, strict) {
var key;
if (strict) {
for (key in haystack) {
if (!haystack.hasOwnProperty[key]) continue;
if (haystack[key] === needle) {
return true;
}
}
} else {
for (key in haystack) {
if (!haystack.hasOwnProperty[key]) continue;
if (haystack[key] == needle) {
return true;
}
}
}
return false;
}