web-dev-qa-db-ja.com

配列が多次元かどうかを確認していますか?

  1. 配列がプリミティブ値のフラット配列かどうか、または多次元配列かどうかをチェックする最も効率的な方法は何ですか?
  2. 実際に配列をループして各要素でis_array()を実行せずにこれを行う方法はありますか?
127
Wilco

短い答えはいいえです。「2番目の次元」がどこかにある可能性がある場合、少なくとも暗黙的にループせずにそれを行うことはできません。それが最初の項目になければならない場合、あなたはただやります

is_array($arr[0]);

しかし、私が見つけることができる最も効率的な一般的な方法は、配列でforeachループを使用して、ヒットが見つかるたびに短絡することです(少なくとも暗黙的なループは、まっすぐなfor()よりも優れています):

$ more multi.php
<?php

$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');
$c = array(1 => 'a',2 => 'b','foo' => array(1,array(2)));

function is_multi($a) {
    $rv = array_filter($a,'is_array');
    if(count($rv)>0) return true;
    return false;
}

function is_multi2($a) {
    foreach ($a as $v) {
        if (is_array($v)) return true;
    }
    return false;
}

function is_multi3($a) {
    $c = count($a);
    for ($i=0;$i<$c;$i++) {
        if (is_array($a[$i])) return true;
    }
    return false;
}
$iters = 500000;
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
    is_multi($a);
    is_multi($b);
    is_multi($c);
}
$end = microtime(true);
echo "is_multi  took ".($end-$time)." seconds in $iters times\n";

$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
    is_multi2($a);
    is_multi2($b);
    is_multi2($c);
}
$end = microtime(true);
echo "is_multi2 took ".($end-$time)." seconds in $iters times\n";
$time = microtime(true);
for ($i = 0; $i < $iters; $i++) {
    is_multi3($a);
    is_multi3($b);
    is_multi3($c);
}
$end = microtime(true);
echo "is_multi3 took ".($end-$time)." seconds in $iters times\n";
?>

$ php multi.php
is_multi  took 7.53565130424 seconds in 500000 times
is_multi2 took 4.56964588165 seconds in 500000 times
is_multi3 took 9.01706600189 seconds in 500000 times

暗黙のループですが、一致が見つかるとすぐに短絡できません...

$ more multi.php
<?php

$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');

function is_multi($a) {
    $rv = array_filter($a,'is_array');
    if(count($rv)>0) return true;
    return false;
}

var_dump(is_multi($a));
var_dump(is_multi($b));
?>

$ php multi.php
bool(true)
bool(false)
128
Vinko Vrsalovic

Count()を2回使用します。デフォルトモードで1回、再帰モードで1回。値が一致する場合、多次元配列の方が再帰カウントが高くなるため、配列は多次元notです。

_if (count($array) == count($array, COUNT_RECURSIVE)) 
{
  echo 'array is not multidimensional';
}
else
{
  echo 'array is multidimensional';
}
_

このオプションの2番目の値modeは、PHP 4.2.0。 PHP Docs から追加されました。

オプションのモードパラメータがCOUNT_RECURSIVE(または1)に設定されている場合、count()は配列を再帰的にカウントします。これは、多次元配列のすべての要素をカウントするのに特に役立ちます。 count()は無限再帰を検出しません。

ただし、このメソッドはarray(array())を検出しません。

181
zash

PHP 4.2.0以降の場合:

function is_multi($array) {
    return (count($array) != count($array, 1));
}
28
scronide

これは最も簡単な方法であり、最先端のものだと思います。

function is_multidimensional(array $array) {
    return count($array) !== count($array, COUNT_RECURSIVE);
}
10
Andreas

これを簡単に実行できます:

if (count($myarray) !== count($myarray, COUNT_RECURSIVE)) return true;
else return false;

オプションのモードパラメータがCOUNT_RECURSIVE(または1)に設定されている場合、count()は配列を再帰的にカウントします。これは、多次元配列のすべての要素をカウントするのに特に役立ちます。

同じ場合、どこにもサブレベルがないことを意味します。簡単で速い!

9
Pian0_M4n

配列の最初の要素が配列である場合、残りの要素も配列であるという仮定の下で、最初の要素のis_array()を確認できます。

7
Greg Hewgill

すべての素晴らしい答え...ここに私がいつも使っている私の3つの行があります

function isMultiArray($a){
    foreach($a as $v) if(is_array($v)) return TRUE;
    return FALSE;
}
4
Joe

この関数は、最も単純で、最も効率的で、最速の方法であることがわかると思います。

function isMultiArray($a){
    foreach($a as $v) if(is_array($v)) return TRUE;
    return FALSE;
}

次のようにテストできます。

$a = array(1 => 'a',2 => 'b',3 => array(1,2,3));
$b = array(1 => 'a',2 => 'b');

echo isMultiArray($a) ? 'is multi':'is not multi';
echo '<br />';
echo isMultiArray($b) ? 'is multi':'is not multi';
2
RoboTamer

この関数は、配列の次元のint数を返します( here から盗まれました)。

function countdim($array)
{
   if (is_array(reset($array))) 
     $return = countdim(reset($array)) + 1;
   else
     $return = 1;

   return $return;
}

次のようにしてください

if (count($arrayList) != count($arrayList, COUNT_RECURSIVE)) 
{
  echo 'arrayList is multidimensional';

}else{

  echo 'arrayList is no multidimensional';
}
1
Arshid KV

私の場合。私は変な奇妙な状態で立ち往生しています。
最初のケース= array("data"=> "name");
2番目のケース= array("data"=> array("name"=>"username","fname"=>"fname"));
ただし、dataに値ではなく配列がある場合、sizeof()またはcount()関数はこの条件では機能しません。次に、チェックするカスタム関数を作成します。
配列の最初のインデックスに値がある場合、「値のみ」を返します
ただし、インデックスに値ではなく配列がある場合、「配列を持つ」を返します
この方法で使用します

 function is_multi($a) {
        foreach ($a as $v) {
          if (is_array($v)) 
          {
            return "has array";
            break;
          }
          break;
        }
        return 'only value';
    }

Vinko Vrsalovic に感謝します

1
Darkcoder

COUNT_RECURSIVEを使用しないでください

理由を知るにはこのサイトをクリックしてください

rsortを使用してからissetを使用します

function is_multi_array( $arr ) {
rsort( $arr );
return isset( $arr[0] ) && is_array( $arr[0] );
}
//Usage
var_dump( is_multi_array( $some_array ) );
1
hendra1

次のような簡単なチェックもできます。

$array = array('yo'=>'dream', 'mydear'=> array('anotherYo'=>'dream'));
$array1 = array('yo'=>'dream', 'mydear'=> 'not_array');

function is_multi_dimensional($array){
    $flag = 0;
    while(list($k,$value)=each($array)){
        if(is_array($value))
            $flag = 1;
    }
    return $flag;
}
echo is_multi_dimensional($array); // returns 1
echo is_multi_dimensional($array1); // returns 0
1
Prashant

上記の方法はすべて、複雑すぎて迅速にロールアウトできません。配列がフラットの場合、最初の要素をテストすると、プリミティブ、int、string e.t.cなどが返されます。多次元の場合、配列を返す必要があります。拡張により、この1つのライナーを高速かつ整然と使用できます。

echo is_array(array_shift($myArray));

これがtrueを返す場合、配列は多次元です。それ以外はフラットです。ただ、配列が異なる次元を持つことは非常にまれです。モデルからデータを生成している場合、モデルは常に、ループが通過できる同じタイプの多次元またはフラット構造を持ちます。 machine made loops そうでない場合は、手動でカスタムビルドします。つまり、すべてがどこにあるかがわかり、ループアルゴリズムを記述することなく機能します enter image description here

0

これでも動作します

is_array(current($array));

falseそのa 単次元配列if trueそのa 多次元配列.

currentは、配列の最初の要素を提供し、最初の要素が配列かどうかをis_array関数で確認します。

0
Priyank

私はこれが上品だと思います(彼のユーザー名がわからない別のユーザーの小道具):

static public function isMulti($array)
{
    $result = array_unique(array_map("gettype",$array));

    return count($result) == 1 && array_shift($result) == "array";
}

そのシンプルな

$isMulti = !empty(array_filter($array, function($e) {
                    return is_array($e);
                }));
0

前の回答に加えて、チェックする配列のスキーマに応じて:

function is_multi_array($array=[],$mode='every_key'){

    $result = false;

    if(is_array($array)){

        if($mode=='first_key_only'){

            if(is_array(array_shift($array))){

                $result = true;
            }
        }
        elseif($mode=='every_key'){

            $result = true;

            foreach($array as $key => $value){

                if(!is_array($value)){

                    $result = false;
                    break;
                }
            }
        }
        elseif($mode=='at_least_one_key'){

            if(count($array)!==count($array, COUNT_RECURSIVE)){

                $result = true; 
            }
        }
    }

    return $result;
}
0
RafaSashi