Kiểm tra xem mảng có đa chiều hay không?


137
  1. Cách hiệu quả nhất để kiểm tra xem một mảng là một mảng phẳng của các giá trị nguyên thủy hay nếu đó là một mảng nhiều chiều ?
  2. Có cách nào để làm điều này mà không thực sự lặp qua một mảng và chạy is_array()trên từng phần tử của nó không?

9
Thật đáng để chỉ ra rằng PHP không có các mảng đa chiều thực sự - chỉ là các mảng liên kết đơn giản của các giá trị. Vì vậy, câu hỏi của bạn thực sự là "có giá trị không vô hướng trong mảng của tôi" không?
gahooa

21
Trên thực tế ... tôi không nghĩ rằng đó là giá trị chỉ ra ở tất cả.
Joe

Câu trả lời:


135

Câu trả lời ngắn gọn là không bạn không thể làm điều đó mà không ít nhất là lặp đi lặp lại nếu "chiều thứ hai" có thể ở bất cứ đâu. Nếu nó phải ở trong mục đầu tiên, bạn chỉ cần làm

is_array($arr[0]);

Nhưng, cách chung hiệu quả nhất mà tôi có thể tìm thấy là sử dụng vòng lặp foreach trên mảng, rút ​​ngắn bất cứ khi nào tìm thấy lần truy cập (ít nhất là vòng lặp ẩn tốt hơn vòng lặp 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

Vòng lặp ngầm định, nhưng chúng ta không thể rút ngắn vòng tròn ngay khi tìm thấy trận đấu ...

$ 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)

3
Tốt, với lời cảnh báo mà tôi tin rằng dòng lọc của bạn nên có mảng_map ("is_array", $ a), không sử dụng is_array làm bareword.
Matthew Scharley

Bắt tốt, tăng tốc là_multi, nhưng vẫn không đủ tốt để phù hợp với foreach
Vinko Vrsalovic

2
Điều đáng chú ý là, như đã viết, multi_3 sẽ chỉ hoạt động trên các mảng không liên kết dựa trên zero, không có khoảng trống trong các chỉ mục, có nghĩa là nó sẽ không xác định chính xác bất kỳ ví dụ nào là đa chiều.
Cragmonkey 19/03/2016

Trong chức năng is_multi()tối ưu hóa mã bằng cách thực hiệnreturn count($rv)>0
Xorifelse

is_array (mảng_values ​​($ Array) [0]) như một cách giải quyết cho các khóa tùy chỉnh.
Vitor Coleues

191

Sử dụng đếm () hai lần; một lần ở chế độ mặc định và một lần ở chế độ đệ quy. Nếu các giá trị khớp nhau, mảng không phải là đa chiều, vì một mảng nhiều chiều sẽ có số đệ quy cao hơn.

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

Giá trị thứ hai tùy chọn này modeđã được thêm vào trong PHP 4.2.0. Từ tài liệu PHP :

Nếu tham số chế độ tùy chọn được đặt thành COUNT_RECURSIVE (hoặc 1), Count () sẽ đếm đệ quy mảng. Điều này đặc biệt hữu ích để đếm tất cả các yếu tố của một mảng nhiều chiều. Count () không phát hiện đệ quy vô hạn.

Tuy nhiên phương pháp này không phát hiện array(array()).


2
Như đã lưu ý, điều này không hoạt động đối với các phần tử có mảng trống
Arthur

30

Đối với PHP 4.2.0 trở lên:

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

Không làm việc cho array(array())hay array(array(), array())một trong hai. Nói chung, nếu một mảng bên trong trống thì số đệ quy sẽ cộng 0 chính xác cho nó, do đó làm cho nó khớp với số bình thường.
Fanis Hatzidakis

13

Tôi nghĩ rằng đây là cách đơn giản nhất và là công nghệ tiên tiến nhất:

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

9

Bạn chỉ có thể thực hiện điều này:

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

Nếu tham số chế độ tùy chọn được đặt thành COUNT_RECURSIVE(hoặc 1), Count () sẽ đếm đệ quy mảng. Điều này đặc biệt hữu ích để đếm tất cả các yếu tố của một mảng nhiều chiều.

Nếu nó giống nhau, có nghĩa là không có cấp dưới ở bất cứ đâu. Dễ dàng và nhanh chóng!


Cảm ơn ... hữu ích. Tôi muốn kiểm tra xem có tồn tại một cấp độ phụ cho mảng của tôi không, tôi đã sử dụngif(count($tasks_by_date) !== count($tasks_by_date, 1))
Mike Barwick

Mát mẻ. COUNT_RECURSIVE hoặc 1 là giống nhau cho số đếm ()
Pian0_M4n

Chắc chắn rồi. Tôi chỉ thích ít lộn xộn hơn và !==đã được sử dụng để xem là cấp phụ tồn tại. Đối với các lý thuyết, những người có thể đang tìm kiếm một cái gì đó tương tự ... vv.
Mike Barwick

Những gì bạn đã không trở lại đúng với tôi ... Tôi cần thêm!==
Mike Barwick

Với mảng trống, đã thất bại
Wallace Maxters

7

Bạn có thể xem xét is_array()phần tử đầu tiên, theo giả định rằng nếu phần tử đầu tiên của một mảng là một mảng, thì phần còn lại của chúng cũng vậy.


Đó thực sự là một điểm tốt. Trong trường hợp cụ thể của tôi, đó là một hoặc hoặc tình huống vì tôi đang kiểm soát việc tạo mảng ban đầu. Bây giờ tôi sẽ để lại câu hỏi trong trường hợp có một giải pháp có thể hoạt động phổ biến hơn.
Wilco

5
Như thế này:if( is_array(current($arr)) ) { // is multidimensional }
Jonas ppelgran

4

Tất cả các câu trả lời tuyệt vời ... đây là ba dòng mà tôi luôn sử dụng

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

2

Hàm này sẽ trả về số lượng kích thước mảng (bị đánh cắp từ đây ).

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

   return $return;
}

Điều này sẽ chỉ làm việc cho trường hợp của Greg. Đó không phải là một giải pháp chung cho vấn đề mà chiều thứ hai có thể ở bất kỳ đâu trong mảng
Vinko Vrsalovic

$ Array = mảng ("xin chào", "hi" => "xin chào"); $ Array [] = & Array; // oops
Tyzoid

2

Tôi nghĩ bạn sẽ thấy rằng chức năng này là cách đơn giản nhất, hiệu quả nhất và nhanh nhất.

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

Bạn có thể kiểm tra nó như thế này:

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

nếu bạn đang đi đến một dòng thì ít nhất hãy làm toàn bộ; foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
Robert Pounder

@RobertPounder hoặc thậm chíforeach($a as $v) return is_array($v) ? true : false;
Yassine Sedrani

2

Sau PHP 7, bạn có thể làm một cách đơn giản:

public function is_multi(array $array):bool
{
    return is_array($array[array_key_first($array)]);
}

1

Bạn cũng có thể thực hiện một kiểm tra đơn giản như thế này:

$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

Hãy thử như sau

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

}else{

  echo 'arrayList is no multidimensional';
}

1

Ngay cả điều này làm việc

is_array(current($array));

Nếu sai thì đó là mảng một chiều nếu đúngđa chiều mảng .

current sẽ cung cấp cho bạn phần tử đầu tiên của mảng của bạn và kiểm tra xem phần tử đầu tiên có phải là một mảng hay không bởi hàm is_array .


Điều đó sẽ không đáng tin nếu bạn muốn đảm bảo rằng bất kỳ yếu tố nào khác cũng không được lồng vào nhau.
vanamerongen


1

Trong trường hợp của tôi. Tôi bị mắc kẹt trong tình trạng kỳ lạ khác nhau.
Trường hợp thứ nhất = Trường hợp array("data"=> "name");
thứ 2 = array("data"=> array("name"=>"username","fname"=>"fname"));
Nhưng nếu datacó mảng thay vì giá trị thì hàm sizeof () hoặc Count () không hoạt động cho điều kiện này. Sau đó, tôi tạo chức năng tùy chỉnh để kiểm tra.
Nếu chỉ mục đầu tiên của mảng có giá trị thì nó trả về "chỉ giá trị"
Nhưng nếu chỉ mục có mảng thay vì giá trị thì nó trả về "có mảng"
Tôi sử dụng cách này

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

Đặc biệt cảm ơn Vinko Vrsalovic


0

Tôi nghĩ rằng cái này là sang trọng (đạo cụ cho người dùng khác mà tôi không biết tên người dùng của anh ấy):

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

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

0

Tất cả các phương pháp trên là quá phức tạp để nhanh chóng triển khai. Nếu một mảng phẳng, kiểm tra phần tử đầu tiên sẽ trả về một nguyên hàm, ví dụ int, chuỗi, v.v ... Nếu nó là đa chiều, nó sẽ trả về một mảng. Bằng cách mở rộng, bạn có thể sử dụng một lớp lót này nhanh chóng và gọn gàng.

echo is_array(array_shift($myArray));

nếu điều này trả về true, mảng là đa chiều. Khác nó là phẳng. Chỉ cần lưu ý, rất hiếm khi các mảng có các kích thước khác nhau, ví dụ nếu bạn đang tạo dữ liệu từ một mô hình, nó sẽ luôn có cùng loại cấu trúc đa chiều hoặc phẳng có thể đi qua các vòng. máy làm vòng Nếu không, thì bạn đã tùy chỉnh xây dựng nó bằng tay, điều đó có nghĩa là bạn biết mọi thứ sẽ ở đâu và nó chỉ hoạt động mà không cần phải viết một thuật toán lặp nhập mô tả hình ảnh ở đây


Kỹ thuật này chỉ tìm thấy các mảng nhiều chiều nếu phần tử đầu tiên là một mảng.
Cragmonkey 19/03/2016

Hãy thận trọng với việc sử dụng array_shift(), vì nó loại bỏ phần tử đầu tiên và cũng đặt lại các phím số! Sử dụng tốt hơn current()nếu vẫn còn ngứa cho một lớp lót.
Marcello Mönkemeyer

0

Ngoài các câu trả lời trước và tùy thuộc vào lược đồ của mảng bạn muốn kiểm tra:

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

Nó đơn giản như

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

0
$is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);

Đây là một lót tốt đẹp. Nó lặp lại trên mỗi khóa để kiểm tra xem giá trị tại khóa đó có phải là một mảng không. Điều này sẽ đảm bảo đúng


-1
if($array[0]){
//enter your code 
}

Ít nhất là sử dụng if (isset($array[0])) { }. Nếu bạn chắc chắn các chỉ mục của mảng bắt đầu từ 0
Aistis

Mảng đa chiều là một mảng chứa một hoặc nhiều mảng. Điều này chỉ kiểm tra xem nó có chứa một phần tử có khóa bằng không.
Cragmonkey 19/03/2016

-1
if ( array_key_exists(0,$array) ) {

// multidimensional array

}  else {

// not a multidimensional array

}

* chỉ với những mảng có chỉ số


Mảng đa chiều là một mảng chứa một hoặc nhiều mảng. Điều này chỉ kiểm tra xem nó có chứa một phần tử có khóa bằng không.
Cragmonkey 19/03/2016

-1

Hàm print_r riêng trả về một chuỗi có thể đọc được. Chỉ cần đếm các trường hợp "Mảng".

thử...

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)

Trên hộp của tôi, "is_multi mất 0.83681297302246 giây trong 500000 lần"

Lịch sự: Ruach HaKodesh



-3
is_array($arr[key($arr)]); 

Không có vòng lặp, đơn giản và đơn giản.

Cũng hoạt động với các mảng liên kết không chỉ các mảng số, không thể chứa 0 (như trong ví dụ trước sẽ đưa ra cảnh báo nếu mảng không có 0.)


Một mảng không thể được phát hiện trên khóa, bạn phải kiểm tra giá trị
RoboTamer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.