web-dev-qa-db-ja.com

オブジェクトが配列かどうかを調べる方法は?

私は、文字列のリストか単一の文字列のどちらかを受け付ける関数を書きたいと思っています。もしそれが文字列なら、私はそれをたった一つの要素を持つ配列に変換したいのです。それから私はエラーを恐れずにそれをループすることができます。

それでは、変数が配列かどうかをどうやって確認すればよいでしょうか。


私は以下のさまざまな解決策をまとめて、 jsperfテスト を作成しました。

2420
mpen

現代のブラウザではあなたができる

Array.isArray(obj)

Chrome 5、Firefox 4.0、IE 9、Opera 10.5、およびSafari 5でサポートされています)

下位互換性のために、以下を追加することができます。

# only implement if no native implementation is available
if (typeof Array.isArray === 'undefined') {
  Array.isArray = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  }
};

JQueryを使用している場合は、jQuery.isArray(obj)または$.isArray(obj)を使用できます。アンダースコアを使用する場合は、_.isArray(obj)を使用できます。

異なるフレームで作成された配列を検出する必要がない場合は、instanceofを使用することもできます。

obj instanceof Array
556

Objectのクラスを見つけるためにECMAScript標準で与えられた方法は、Object.prototypeからのtoStringメソッドを使うことです。

if( Object.prototype.toString.call( someVar ) === '[object Array]' ) {
    alert( 'Array!' );
}

あるいはtypeofを使ってそれが文字列かどうかをテストすることもできます。

if( typeof someVar === 'string' ) {
    someVar = [ someVar ];
}

あるいは、パフォーマンスを気にしないのであれば、新しい空の配列に対してconcatを実行することもできます。

someVar = [].concat( someVar );

直接問い合わせることができるコンストラクタもあります。

if (somevar.constructor.name == "Array") {
    // do something
}

下記のコメントに掲載されているように、 @ T.J。Crowder's から 徹底した取り扱い )をチェックしてください。

どの方法がより良いパフォーマンスを発揮するかについては、この benchmark をご覧ください。 http://jsben.ch/#/QgYAV

@Bharath から、質問にEs6を使用して文字列を配列に変換します。

const convertStringToArray = (object) => {
   return (typeof object === 'string') ? Array(object) : object 
}

と思います。 

let m = 'bla'
let n = ['bla','Meow']
let y = convertStringToArray(m)
let z = convertStringToArray(n)
console.log('check y: '+JSON.stringify(y)) . // check y: ['bla']
console.log('check y: '+JSON.stringify(z)) . // check y: ['bla','Meow']
1896
user113716

まずあなたの実装がisArrayをサポートしているかどうかチェックします。

if (Array.isArray)
    return Array.isArray(v);

instanceof演算子を使ってみることもできます

v instanceof Array
1238
ChaosPandion

jQueryは $.isArray() メソッドも提供します。

var a = ["A", "AA", "AAA"];

if($.isArray(a)) {
  alert("a is an array!");
} else {
  alert("a is not an array!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

288
janr

これはすべての方法の中で最も速い(すべてのブラウザがサポートされている)。

function isArray(obj){
    return !!obj && obj.constructor === Array;
}
92
shinobi

以下の配列があると想像してください。 

var arr = [1,2,3,4,5];

Javascript(新旧のブラウザ):

function isArray(arr) {
  return arr.constructor.toString().indexOf("Array") > -1;
}

または

function isArray(arr) {
  return arr instanceof Array;
}

または 

function isArray(arr) {
  return Object.prototype.toString.call(arr) === '[object Array]';
}

それを次のように呼びます。

isArray(arr);

Javascript(IE9 +、Ch5 +、FF4 +、Saf5 +、Opera10.5 +) 

Array.isArray(arr);

jQuery:

$.isArray(arr);

角:

angular.isArray(arr);

アンダースコアとロダッシュ:

_.isArray(arr);
36
Alireza

Array.isArrayは高速に動作しますが、すべてのバージョンのブラウザでサポートされているわけではありません。

    Utils = {};    
    Utils.isArray = ('isArray' in Array) ? 
        Array.isArray : 
        function (value) {
            return Object.prototype.toString.call(value) === '[object Array]';
        }
32
CruorVult

これをチェックする簡単な機能:

function isArray(object)
{
    if (object.constructor === Array) return true;
    else return false;
}
22

この質問にはたった1行の解決策があります

x instanceof Array

xが変数の場合、xが配列の場合はtrueを返し、そうでない場合はfalseを返します。

14
Vikash Kumar

MDNが言うように ここで

Array.isArray または Object.prototype.toString.call を使用して、正規オブジェクトと配列を区別

このような:

  • Object.prototype.toString.call(arr) === '[object Array]'、または

  • Array.isArray(arr)

14
ajax333221

私はあなたが扱っているオブジェクトのタイプをテストするための関数を作ります...

function whatAmI(me){ return Object.prototype.toString.call(me).split(/\W/)[2]; }

// tests
console.log(
  whatAmI(["aiming","@"]),
  whatAmI({living:4,breathing:4}),
  whatAmI(function(ing){ return ing+" to the global window" }),
  whatAmI("going to do with you?")
);

// output: Array Object Function String

それならあなたは簡単なif文を書くことができます...

if(whatAmI(myVar) === "Array"){
    // do array stuff
} else { // could also check `if(whatAmI(myVar) === "String")` here to be sure
    // do string stuff
}
13
Billy Moon

あなたはそれが配列であるかどうかあなたの変数の型をチェックすることができます。

var myArray=[];

if(myArray instanceof Array)
{
....
}
13
Ahmet DAL

私はこれを非常に簡単な方法で行います。私のために働きます。どんな欠点がありますか?

Array.prototype.isArray = true;

a=[]; b={};
a.isArray  // true
b.isArray  // (undefined -> false)
11
rsbkk

これは この答え を考慮して改善するための私の試みです:

var isArray = myArray && myArray.constructor === Array;

それはif/elseを取り除き、配列がnullまたは未定義である可能性を説明します

11
George Jempty

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray

Array.isArray = Array.isArray || function (vArg) {
    return Object.prototype.toString.call(vArg) === "[object Array]";
};
10
Safareli

jsperfフィドル を2つの代替方法とエラーチェックで更新しました。

'Object'プロトタイプと 'Array'プロトタイプで定数値を定義するメソッドは、他のどのメソッドよりも高速であることがわかります。やや驚くべき結果です。

/* Initialisation */
Object.prototype.isArray = function() {
  return false;
};
Array.prototype.isArray = function() {
  return true;
};
Object.prototype._isArray = false;
Array.prototype._isArray = true;

var arr = ["1", "2"];
var noarr = "1";

/* Method 1 (function) */
if (arr.isArray()) document.write("arr is an array according to function<br/>");
if (!noarr.isArray()) document.write("noarr is not an array according to function<br/>");
/* Method 2 (value) - **** FASTEST ***** */
if (arr._isArray) document.write("arr is an array according to member value<br/>");
if (!noarr._isArray) document.write("noarr is not an array according to member value<br/>");

これら2つの方法は、変数が未定義の値をとる場合は機能しませんが、値があることが確実な場合は機能します。値が配列であるか単一の値であるかを念頭に置いてパフォーマンスをチェックすることに関して、2番目の方法は有効な高速な方法のように見えます。これは、Chrome上の 'instanceof'よりもわずかに速く、Internet Explorer、Opera、およびSafari(私のマシン上)の2番目に良い方法の2倍の速さです。

10
le_top

私は知っている、人々は何らかの種類の生のjavascriptアプローチを探しています。しかし、あまり考えたくない場合は、こちらをご覧ください: http://underscorejs.org/#isArray

_.isArray(object) 

オブジェクトが配列の場合、trueを返します。

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true
9
Eugene

私が見た中で最良の解決策は、typeofの代わりにクロスブラウザを使うことです。 Angus Crollの解決策をチェックしてください ここ

TL; DRのバージョンは以下の通りですが、この記事はこの問題についての素晴らしい議論です。

Object.toType = function(obj) {
    return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
}
// ... and usage:
Object.toType([1,2,3]); //"array" (all browsers)

// or to test...
var shouldBeAnArray = [1,2,3];
if(Object.toType(shouldBeAnArray) === 'array'){/* do stuff */};
5
John Wundes

Stoyan Stefanovの著書 JavaScript Patterns には、ECMAScript 5のメソッド Array.isArray() を利用するだけでなく、考えられるすべての問題を処理するための良い例があります。

だからここにあります:

if (typeof Array.isArray === "undefined") {
    Array.isArray = function (arg) {
        return Object.prototype.toString.call(arg) === "[object Array]";
    };
}

ところで、あなたがjQueryを使っているなら、あなたはそれを使うことができます $ .isArray()

5
Salvador Dali

これが私の怠惰なアプローチです。

if (Array.prototype.array_ === undefined) {
  Array.prototype.array_ = true;
}

// ...

var test = [],
    wat = {};

console.log(test.array_ === true); // true
console.log(wat.array_ === true);  // false

プロトタイプを「めちゃくちゃにする」のは不名誉だと思いますが、 推奨されたtoStringメソッドよりもはるかに優れたパフォーマンスを発揮するようです

注: このアプローチの落とし穴は iframeの境界を越えて動作しないことです しかし、私のユースケースではこれは問題ではありません。

5
namuol

あなたのオブジェクトがconcatメソッドを持っていないことを知っているならば、以下が使用されるかもしれません。

var arr = [];
if (typeof arr.concat === 'function') {
    console.log("It's an array");
}

5
yesil

オブジェクトが配列かどうかを確認する最も簡単で速い方法です。

 var arr = [];
  arr.constructor.name ==='Array'  //return true;

または 

arr.constructor ===Array //return true;

あるいはユーティリティ関数を作ることもできます。

function isArray(obj){ return obj && obj.constructor ===Array}

使用法:

isArray(arr); //return true
5
sheelpriy

あなたはisArrayメソッドかもしれません 

Object.getPrototypeOf(yourvariable) === Array.prototype

5
STEEL

入力値が配列かどうかをテストするための簡単な関数は次のとおりです。

function isArray(value)
{
  return Object.prototype.toString.call(value) === '[object Array]';
}

これはクロスブラウザでも古いブラウザでも動作します。これは T.Jから取得したものです。 Crowdersのブログ投稿

4
Brad Parks

この関数はほとんどすべてを配列に変換します。

function arr(x) {
    if(x === null || x === undefined) {
        return [];
    }
    if(Array.isArray(x)) {
        return x;
    }
    if(isString(x) || isNumber(x)) {
        return [x];
    }
    if(x[Symbol.iterator] !== undefined || x.length !== undefined) {
        return Array.from(x);
    }
    return [x];
}

function isString(x) {
    return Object.prototype.toString.call(x) === "[object String]"
}

function isNumber(x) {
    return Object.prototype.toString.call(x) === "[object Number]"
}

あなたは最大限のサポートのためにこれを一杯にすることを望むかもしれないので、それはいくつかのより新しいブラウザ機能を使います。

例:

> arr(null);
[]
> arr(undefined)
[]
> arr(3.14)
[ 3.14 ]
> arr(1/0)
[ Infinity ]
> gen = function*() { yield 1; yield 2; yield 3; }
[Function: gen]
> arr(gen())
[ 1, 2, 3 ]
> arr([4,5,6])
[ 4, 5, 6 ]
> arr("foo")
[ 'foo' ]

N.B.文字列は、文字の配列ではなく単一の要素を持つ配列に変換されます。反対にisStringチェックを削除したい場合は削除してください。

ここでArray.isArrayを使用したのは、これが 最も堅牢な そして最も単純なためです。

4
mpen

これを試すことができます:

var arr = []; (or) arr = new Array();
var obj = {}; (or) arr = new Object();

arr.constructor.prototype.hasOwnProperty('Push') //true

obj.constructor.prototype.hasOwnProperty('Push') // false
4
VIJAY P

あなたのケースでは、 Arrayconcatメソッドを使用することができます。これは単一のオブジェクトだけでなく配列も(そして組み合わせても)受け入れることができます。

function myFunc(stringOrArray)
{
  var arr = [].concat(stringOrArray);

  console.log(arr);

  arr.forEach(function(item, i)
  {
    console.log(i, "=", item);
  })
}

myFunc("one string");

myFunc(["one string", "second", "third"]);

concatは、Arrayの最も古いメソッドの1つのようです(たとえIE 5.5でもそれを知っています)。

4
kolyaseg

この関数に渡すことができる2種類の値だけが文字列または文字列の配列である場合は、それを単純にして、文字列の可能性についてtypeofチェックを使用します。

function someFunc(arg) {
    var arr = (typeof arg == "string") ? [arg] : arg;
}
4
Tim Down
A = [1,2,3]
console.log(A.map==[].map)

ここで最短バージョンを探しているのは私がこれまでに手に入れたものです。

すべての可能な組み合わせを常に検出する完全な機能はありません。 魔法の道具を期待するよりもあなたの道具のすべての能力と限界を知っているほうがよいです。

4
exebook
function isArray(value) {
    if (value) {
        if (typeof value === 'object') {
            return (Object.prototype.toString.call(value) == '[object Array]')
        }
    }
    return false;
}

var ar = ["ff","tt"]
alert(isArray(ar))
4
RoboTamer

ありがたいことに、ECMA 5は2009年12月にArray.isArray()を導入しました。何らかの理由でECMA 5より古いバージョンのJavaScriptを使用している場合は、アップグレードしてください。

あなたがそれを主張するならば、しかし、それからそれから他のタイプからそれらを区別する特定の特性が配列にあります。私が見たことがない特性は他の答えのどれでも述べなかった。いくつかのJavaScriptの政治に入りましょう。

配列はオブジェクト(typeof [] === "object")ですが、従来のオブジェクトとは異なり、lengthプロパティ(typeof ( {} ).length === "undefined")があります。 nullオブジェクト(typeof null === "object")ですが、nullnotオブジェクトなので、nullのプロパティにアクセスすることはできません。オブジェクトの型タグが0nullがリテラルのヌルポインタ0x00として表現されていたため、インタプリタがオブジェクトと混同していました。 

残念ながら、これは[]{length:0}を説明するものではありません。だから我々は今プロトタイプチェーンに目を向けなければならない。

( [] ).__proto__ === Array.prototype && ( [] ).__proto__ !== Object.prototype

したがって、Array.isArray()がなければ、これはちょうど私たちが得ることができる最も近いものです:

function is_array(array){
    return array !== null
        && typeof array === "object"
        && array.__proto__ === Array.prototype;
}

[ [], [1,2,3], {length: 0}, {},
  1, 0, Infinity, NaN, "1", "[1,2,3]",
  null, undefined, [null], [undefined], {a:[]},
  [{}], [{length: 0}], [Infinity], [NaN],
  {__proto__: Array.prototype}
].filter(is_array)
// Expected: [ [], [1,2,3], [null], [undefined], [{}], [{length: 0}], [Infinity], [NaN] ]
// Actual:   [ [], [1,2,3], [null], [undefined], [{}], [{length: 0}], [Infinity], [NaN], {__proto__: Array.prototype} ]

アレイのように見えるように悪意を持って設計されたオブジェクトは、実際にチューリングテストに合格します。ただし、プロトタイプチェーンをArrayプロトタイプチェーンに置き換えるだけで、アレイのように機能し、効果的に配列にすることができます。そのようなオブジェクトを実際には認識できないのは、Array.isArray()だけです。しかし目的のために、オブジェクトが配列であるかどうかを通常チェックしているならば、そのオブジェクトはあなたのコードでNiceを演じるべきです。配列の長さを人為的に変更した場合の動作も同じです。長さが配列内の要素数より長い場合は、「空のスロット」が特殊な「暗黙的に定義されていない」型とは異なるのです。 === undefinedであると同時に未定義。 ReferenceErrorが明示的にobjとして定義されている場合はtypeof obj !== "undefined" only notがエラーをスローするため、undefinedをスローしないようにするためにobj === undefinedを使用するのとまったく同じ型.

a = {__proto__: Array.prototype}; // Array {}
a.Push(5)
a // [5]
a.length = 5
a // [5, empty x 4]
b = a.map(n => n*n) // [25, empty x 4]
b.Push(undefined)
b.Push(undefined)
b // [25, empty x 4, undefined, undefined]
b[1] // undefined
b[1] === b[5] // true
Array.isArray(a) // false
Array.isArray(b) // true

ただし、is_array()は使わないでください。それは学習目的のために車輪を再発明することの一つです。プロダクションコードでそれをすることは別のことです。ポリフィルとしても使用しないでください。古いバージョンのJSをサポートするということは、古いブラウザをサポートするということは、安全でないソフトウェアの使用を奨励することを意味し、ユーザーをマルウェアの危険にさらすことを意味します。

3
Braden Best

確認するための他の方法も存在しますが、私は確認するのが私の最善策として次の方法を好みます(他のオブジェクトのタイプを簡単に確認できるため)。

> a = [1, 2]
[ 1, 2 ]
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>
> Object.prototype.toString.call([]).slice(8,-1) // best approach
'Array'

説明(Node REPLの簡単な例を含む)»

> o = {'ok': 1}
{ ok: 1 }
> a = [1, 2]
[ 1, 2 ]
> typeof o
'object'
> typeof a
'object'
>
> Object.prototype.toString.call(o)
'[object Object]'
> Object.prototype.toString.call(a)
'[object Array]'
>

オブジェクトまたは配列»

> Object.prototype.toString.call(o).slice(8,).replace(/\]$/, '')
'Object'
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>

NULLまたは未定義»

> Object.prototype.toString.call(undefined).slice(8,).replace(/\]$/, '')
'Undefined'
> Object.prototype.toString.call(null).slice(8,).replace(/\]$/, '')
'Null'
>

文字列»

> Object.prototype.toString.call('ok').slice(8,).replace(/\]$/, '')
'String'

番号»

> Object.prototype.toString.call(19).slice(8,).replace(/\]$/, '')
'Number'
> Object.prototype.toString.call(19.0).slice(8,).replace(/\]$/, '')
'Number'
> Object.prototype.toString.call(19.7).slice(8,).replace(/\]$/, '')
'Number'
>

以下のように、正規表現の代わりに-1を使用することを@mpenが提案したことに感謝します。

> Object.prototype.toString.call(12).slice(8,-1)
'Number'
>
> Object.prototype.toString.call(12.0).slice(8,-1)
'Number'
>
> Object.prototype.toString.call([]).slice(8,-1)
'Array'
> Object.prototype.toString.call({}).slice(8,-1)
'Object'
>
> Object.prototype.toString.call('').slice(8,-1)
'String'
>
1
hygull
var is_array = function (value) {
   return value &&
     typeof value === 'object' &&
     typeof value.length === 'number' &&
     typeof value.splice === 'function' &&
    !(value.propertyIsEnumerable('length'));
};

この機能は、 "JS the good parts"の本から引用しています。

1
user3367643

配列のlengthプロパティで確認することもできます。配列の長さプロパティにアクセスしようとすると、数値(空の配列の場合は0)が返されます。オブジェクトの長さプロパティにアクセスしようとすると、undefinedが返されます。

if(Object.prototype.toString.call(arrayList) === '[object Array]') {
  console.log('Array!');
}

私はこれが古い質問であることを知っています、しかし私は今最も短い答えを見つけました:

var x = [1,2,3]
console.log(x.map?1:0)

私はこれが古い質問であることを知っています、しかしここに私が思いつきそして私のプロジェクトのために使ってきた解決策があります...

function isArray (o) {
    return typeof o === "object" && o.length !== undefined;
}

isArray({}); // false
isArray(1); // false
isArray("str"); // false
isArray(function(){}); // false

isArray([]); // true

唯一の落とし穴は、あなたのオブジェクトがたまたま長さのプロパティを持っている場合、それが誤ったポジティブを与えるということです:

isArray({length:0}); // true

その欠点に問題がなく、純粋なオブジェクトにそのプロパティがないことを知っているなら、それはきれいな解決策であり、Object.prototype.toString.callメソッドより速いはずです。

0
Sensei_Shoh

最初にconsole.log(typeof Object)を確認できます

出力がオブジェクトの場合、var {data} = object、つまりオブジェクトキーに従ってオブジェクトを単に非構造化します。関数は次のようになります。

const abc=(str1,str2=null)=>{


     var result=[];
      result.Push(str1);result.Push(str2);
      return result.join("");

}
0
Souvik Dey

プロトタイプとArray.isArrayのチェックアウトには違いがあります。

function isArray(obj){
    return Object.getPrototypeOf(obj) === Array.prototype
}

この関数はobjが配列かどうかを直接チェックします

しかし、このProxyオブジェクトの場合:

var arr = [1,2,3]

var proxy = new Proxy(arr,{})

console.log(Array.isArray(proxy)) // true

Array.isArrayはそれをArrayと見なします。

0
saltfish

ベストプラクティスはconstructorを使って比較することです。

if(some_variable.constructor === Array){
  // do something
}

typeOfのような他の方法を使うこともできます。それを文字列に変換してから比較しますが、dataTypeと比較することは常により良い方法です。

0
Atishay Jain

この関数を使ってデータ型を取得することができます。

var myAr  = [1,2];

checkType(myAr);

function checkType(data){
  if(typeof data ==='object'){
    if(Object.prototype.toString.call(data).indexOf('Array')!==(-1)){
      return 'array';
    } else{
      return 'object';
    }
  } else {
    return typeof data;
  }
}

if(checkType(myAr) === 'array'){console.log('yes, It is an array')};
0

Object.prototypeの呼び出しは好きではないので、他の解決策を探しました。特にChaosPandionの解決策が常にうまくいくとは限らず、MidnightTortoiseとisArray()の解決策はDOMから来る配列ではうまくいかない( getElementsByTagName のように)。そしてついに私は簡単でクロスブラウザのソリューションを見つけました。それもおそらくNetscape 4でうまくいったでしょう。

それはちょうどこれらの4行です(どんなオブジェクトhもチェックします):

function isArray(h){
    if((h.length!=undefined&&h[0]!=undefined)||(h.length===0&&h[0]===undefined)){
        return true;
    }
    else{ return false; }
}

私はすでにこれらの配列をテストしました(すべてtrueを返します):

1) array=d.getElementsByName('some_element'); //'some_element' can be a real or unreal element
2) array=[];
3) array=[10];
4) array=new Array();
5) array=new Array();
   array.Push("whatever");

これがすべてのケースに有効であることを誰かが確認できますか?それとも私の解決策がうまくいかないケースを誰かが見つけますか?

0
Marcus

これは、(私とは異なり)JSの学習中に早い段階で知っておくべき配列の重要な事実を説明するコードスニペットです。

// this functions puts a string inside an array
var stringInsideArray = function(input) {
  if (typeof input === 'string') {
    return [input];
  }
  else if (Array.isArray(input)) {
    return input;
  } 
  else {
    throw new Error("Input is not a string!");
  }
}

var output = stringInsideArray('hello');
console.log('step one output: ', output); // ["hello"]

// use typeof method to verify output is an object
console.log('step two output: ', typeof output); // object

// use Array.isArray() method to verify output is an array
console.log('step three output: ', Array.isArray(output)); // true

配列 、実際にはオブジェクトです。

typeof 演算子を使用して、stringInsideArray('hello')の出力は["hello"] 本当に オブジェクトであることを証明します。配列はJavaScriptのデータ型になると私は思っていたので、これは私にとって最も長い時間のために私を困惑させました...

JSデータ型は7つしかなく、配列は _ではなく_ のいずれかです。

あなたの質問に答えるために、 Array.isArray() メソッドを使うことはoutputが配列であることを決定します。

0
underthecode

Array.isArrayは、これを実行する方法です。例えば:

var arr = ['tuna', 'chicken', 'pb&j'];
var obj = {sandwich: 'tuna', chips: 'cape cod'};

// Returns true
Array.isArray(arr);

// Return false
Array.isArray(obj);

0
bijayshrestha

あなたは以下のようにPushで見つけることができます:

function isArray(obj){
   return (typeof obj.Push=== 'function')?true:false;
}

var array=new Array();
or
var array=['a','b','c'];
console.log(isArray(array));

0
lalithkumar