配列が多次元かどうかを確認していますか?
-
02-07-2019 - |
質問
- 配列がフラット配列であるかどうかを確認する最も効率的な方法は何ですか プリミティブ値のまたはそれが多次元配列である場合?
- 実際にループすることなくこれを行う方法はありますか
配列と各要素で
is_array()
を実行していますか?
解決
「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)
他のヒント
count()を2回使用します。デフォルトモードで1回、再帰モードで1回。値が一致する場合、多次元配列の再帰カウントは高くなるため、配列は多次元ではありません 。
if (count($array) == count($array, COUNT_RECURSIVE))
{
echo 'array is not multidimensional';
}
else
{
echo 'array is multidimensional';
}
このオプションの2番目の値 mode
は、PHP 4.2.0で追加されました。 PHPドキュメントから:
オプションのモードパラメータがCOUNT_RECURSIVE(または1)に設定されている場合、count()は配列を再帰的にカウントします。これは、多次元配列のすべての要素をカウントするのに特に便利です。 count()は無限再帰を検出しません。
ただし、このメソッドは array(array())
を検出しません。
PHP 4.2.0以降の場合:
function is_multi($array) {
return (count($array) != count($array, 1));
}
これは最も単純な方法であり、最新技術であると思います:
function is_multidimensional(array $array) {
return count($array) !== count($array, COUNT_RECURSIVE);
}
これを実行するだけです:
if (count($myarray) !== count($myarray, COUNT_RECURSIVE)) return true;
else return false;
オプションのモードパラメータが COUNT_RECURSIVE
(または1)に設定されている場合、count()は配列を再帰的にカウントします。これは、多次元配列のすべての要素をカウントするのに特に役立ちます。
同じ場合、サブレベルはどこにもありません。簡単で速い!
配列の最初の要素が配列である場合、残りの要素も配列であるという仮定の下で、最初の要素の is_array()
を確認できます。
すべての素晴らしい答え...私がいつも使用している私の3行です
function isMultiArray($a){
foreach($a as $v) if(is_array($v)) return TRUE;
return FALSE;
}
この関数は、配列の次元のint数を返します(こちら)。
function countdim($array)
{
if (is_array(reset($array)))
$return = countdim(reset($array)) + 1;
else
$return = 1;
return $return;
}
この関数は、最も単純で、最も効率的で、最速の方法であることがわかると思います。
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';
次のような簡単なチェックもできます。
$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
次のように試してください
if (count($arrayList) != count($arrayList, COUNT_RECURSIVE))
{
echo 'arrayList is multidimensional';
}else{
echo 'arrayList is no multidimensional';
}
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 ) );
これは上品だと思います(ユーザー名がわからない別のユーザーの小道具):
static public function isMulti($array)
{
$result = array_unique(array_map("gettype",$array));
return count($result) == 1 && array_shift($result) == "array";
}
上記のすべての方法は、迅速にロールアウトするには複雑すぎます。配列がフラットの場合、最初の要素をテストすると、プリミティブ、int、string e.t.cなどが返されます。多次元の場合、配列を返す必要があります。拡張により、この1つのライナーを高速かつきれいに使用できます。
echo is_array(array_shift($myArray));
これがtrueを返す場合、配列は多次元です。それ以外はフラットです。ただ、配列が異なる次元を持つことは非常にまれです。モデルからデータを生成している場合、モデルは常に、ループが通過できる同じタイプの多次元またはフラット構造を持ちます。 そうでない場合は、手動でカスタムビルドします。つまり、すべてがどこにあるかを知っており、ループアルゴリズムを記述する必要なく動作するだけです。
前の回答に加えて、チェックする配列のスキーマに応じて:
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;
}
これでも動作します
is_array(current($array));
false の場合は単次元配列、 true の場合は複数次元配列。
current は、配列の最初の要素を提供し、 is_array 関数によって最初の要素が配列かどうかを確認します。
私の場合。さまざまな奇妙な状態に陥りました。
1番目のケース= array(&quot; data&quot; =&gt;&quot; name&quot;);
2番目のケース= array(&quot; data&quot; =&gt; array(&quot; name&quot; =&gt;&quot; username&quot;、&quot; fname&quot; =&gt;&quot; fname&quot;));
ただし、 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 に感謝p>
と同じくらい簡単です
$isMulti = !empty(array_filter($array, function($e) {
return is_array($e);
}));
if($array[0]){
//enter your code
}
if ( array_key_exists(0,$array) ) {
// multidimensional array
} else {
// not a multidimensional array
}
*数値インデックスを持つ配列のみ
ネイティブのprint_r関数は、人間が読める文字列を返します。 「配列」を数えるだけですインスタンス。
試用...
substr_count(print_r([...array...], true), 'Array') > 1;
$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)));
$d = array(array());
$e = array(1, array());
$f = array(array(), array());
$g = array("hello", "hi" => "hi there");
$h[] = $g;
var_dump(substr_count(print_r($a, true), 'Array') > 1);
...
//a: bool(true)
//b: bool(false)
//c: bool(true)
//d: bool(true)
//e: bool(true)
//f: bool(true)
//g: bool(false)
//h: bool(true)
私のボックスでは、「is_multiは500000回で0.83681297302246秒かかりました」
提供:Ruach HaKodesh
function isMultiArray(array $value)
{
return is_array(reset($value));
}
is_array($arr[key($arr)]);
ループなし、プレーンでシンプル。
0を含むことができなかった数値配列だけでなく、関連する配列でも動作します(前の例のように、配列に0がない場合は警告がスローされます)。