- 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 ?
- 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?
is_array()
trên từng phần tử của nó không?Câu trả lời:
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)
is_multi()
tối ưu hóa mã bằng cách thực hiệnreturn count($rv)>0
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())
.
Đối với PHP 4.2.0 trở lên:
function is_multi($array) {
return (count($array) != count($array, 1));
}
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.
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!
if(count($tasks_by_date) !== count($tasks_by_date, 1))
!==
đã đượ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.
!==
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.
if( is_array(current($arr)) ) { // is multidimensional }
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;
}
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';
foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
foreach($a as $v) return is_array($v) ? true : false;
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)]);
}
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
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 là đ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 .
Không sử dụng COUNT_RECURSIVE
nhấp vào trang web này để biết lý do tại sao
sử dụng rsort và sau đó sử dụng ngay lập tức
function is_multi_array( $arr ) {
rsort( $arr );
return isset( $arr[0] ) && is_array( $arr[0] );
}
//Usage
var_dump( is_multi_array( $some_array ) );
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 data
có 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
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";
}
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. 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
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.
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;
}
Nó đơn giản như
$isMulti = !empty(array_filter($array, function($e) {
return is_array($e);
}));
if($array[0]){
//enter your code
}
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
if ( array_key_exists(0,$array) ) {
// multidimensional array
} else {
// not a multidimensional array
}
* chỉ với những mảng có chỉ số
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
function isMultiArray(array $value)
{
return is_array(reset($value));
}
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.)