- วิธีที่มีประสิทธิภาพมากที่สุดในการตรวจสอบว่าอาร์เรย์เป็นอาร์เรย์แบบแบนของค่าดั้งเดิมหรือเป็นอาร์เรย์หลายมิติได้อย่างไร
- มีวิธีการทำเช่นนี้โดยไม่วนลูปผ่านอาร์เรย์และทำงาน
is_array()
ในแต่ละองค์ประกอบหรือไม่
is_array()
ในแต่ละองค์ประกอบหรือไม่คำตอบ:
คำตอบสั้น ๆ คือคุณไม่สามารถทำได้โดยไม่วนซ้ำอย่างน้อยถ้าหาก 'มิติที่สอง' สามารถอยู่ที่ใดก็ได้ ถ้ามันจะต้องอยู่ในรายการแรกคุณจะทำ
is_array($arr[0]);
แต่วิธีทั่วไปที่มีประสิทธิภาพที่สุดที่ฉันสามารถหาได้คือการใช้ foreach loop บนอาเรย์, shortcircuiting ทุกครั้งที่พบการตี
$ 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)
is_multi()
เพิ่มประสิทธิภาพรหัสโดยการทำreturn count($rv)>0
ใช้จำนวน () สองครั้ง หนึ่งครั้งในโหมดเริ่มต้นและหนึ่งครั้งในโหมดเรียกซ้ำ ถ้าค่าตรงกันอาร์เรย์ไม่ใช่หลายมิติเนื่องจากอาร์เรย์หลายมิติจะมีจำนวนการเรียกซ้ำที่สูงกว่า
if (count($array) == count($array, COUNT_RECURSIVE))
{
echo 'array is not multidimensional';
}
else
{
echo 'array is multidimensional';
}
ตัวเลือกนี้mode
มีการเพิ่มค่าที่สองใน PHP 4.2.0 จากเอกสาร PHP :
หากพารามิเตอร์โหมดตัวเลือกถูกตั้งค่าเป็น COUNT_RECURSIVE (หรือ 1) การนับ () จะนับอาร์เรย์ซ้ำ สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับการนับองค์ประกอบทั้งหมดของอาร์เรย์หลายมิติ count () ตรวจไม่พบการเรียกซ้ำไม่สิ้นสุด
array(array())
อย่างไรก็ตามวิธีการนี้ไม่ได้ตรวจสอบ
สำหรับ PHP 4.2.0 หรือใหม่กว่า:
function is_multi($array) {
return (count($array) != count($array, 1));
}
array(array())
หรือarray(array(), array())
อย่างใดอย่างหนึ่ง โดยทั่วไปถ้าอาร์เรย์ภายในว่างเปล่าการนับซ้ำจะเพิ่ม 0 อย่างถูกต้องดังนั้นจึงทำให้ตรงกับการนับปกติ
ฉันคิดว่านี่เป็นวิธีที่ตรงไปตรงมาที่สุดและเป็นสุดยอด:
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 () จะนับอาร์เรย์ซ้ำ สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับการนับองค์ประกอบทั้งหมดของอาร์เรย์หลายมิติ
หากเหมือนกันหมายความว่าไม่มีระดับย่อยใด ๆ ง่ายและรวดเร็ว!
if(count($tasks_by_date) !== count($tasks_by_date, 1))
!==
เคยเห็นคือระดับย่อยมีอยู่ สำหรับทฤษฎีที่อาจมองหาบางสิ่งที่คล้ายกัน ... ฯลฯ
!==
คุณสามารถตรวจสอบis_array()
องค์ประกอบแรกภายใต้สมมติฐานว่าหากองค์ประกอบแรกของอาร์เรย์เป็นอาร์เรย์แล้วส่วนที่เหลือของพวกเขาก็เช่นกัน
if( is_array(current($arr)) ) { // is multidimensional }
คำตอบที่ยอดเยี่ยมทั้งหมด ... นี่คือสามบรรทัดของฉันที่ฉันใช้อยู่ตลอดเวลา
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';
foreach($a as $v) is_array($v) ? return TRUE : return FALSE;
foreach($a as $v) return is_array($v) ? true : false;
หลังจาก PHP 7 คุณสามารถทำได้:
public function is_multi(array $array):bool
{
return is_array($array[array_key_first($array)]);
}
คุณสามารถตรวจสอบง่ายๆเช่นนี้ได้:
$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';
}
แม้แต่งานนี้
is_array(current($array));
หากผิดพลาดของตนมิติเดียวอาร์เรย์ถ้าความจริงของมันหลายมิติอาร์เรย์
ปัจจุบันจะให้องค์ประกอบแรกของอาร์เรย์ของคุณและตรวจสอบว่าองค์ประกอบแรกเป็นอาร์เรย์หรือไม่โดยฟังก์ชั่นis_array
อย่าใช้ 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 ) );
ในกรณีของฉัน ฉันติดอยู่ในสภาพที่แปลกแตกต่างกันไป
1st case = array("data"=> "name");
2nd case = array("data"=> array("name"=>"username","fname"=>"fname"));
แต่ถ้าdata
มี array แทนค่าดังนั้น sizeof () หรือ count () ฟังก์ชั่นไม่ทำงานสำหรับเงื่อนไขนี้ จากนั้นฉันสร้างฟังก์ชั่นที่กำหนดเองเพื่อตรวจสอบ
ถ้า index แรกของ array มีค่ามันจะคืนค่า "only value"
แต่ถ้า index มี array แทนที่จะเป็น value ก็จะคืนค่า "has array"
ฉันใช้วิธีนี้
function is_multi($a) {
foreach ($a as $v) {
if (is_array($v))
{
return "has array";
break;
}
break;
}
return 'only value';
}
ขอขอบคุณเป็นพิเศษกับVinko Vrsalovic
ฉันคิดว่าอันนี้ดีงาม (อุปกรณ์ประกอบฉากกับผู้ใช้อื่นฉันไม่ทราบชื่อผู้ใช้ของเขา):
static public function isMulti($array)
{
$result = array_unique(array_map("gettype",$array));
return count($result) == 1 && array_shift($result) == "array";
}
วิธีการข้างต้นทั้งหมดนั้นซับซ้อนเกินไปสำหรับการนำออกใช้อย่างรวดเร็ว ถ้าอาเรย์นั้นแบนการทดสอบองค์ประกอบแรกควรส่งคืนค่าดั้งเดิมเช่น int, สตริงเป็นต้นหากเป็นหลายมิติก็ควรส่งคืนอาเรย์ คุณสามารถใช้สายการบินเดียวนี้ได้อย่างรวดเร็วและเรียบร้อย
echo is_array(array_shift($myArray));
ถ้าสิ่งนี้คืนค่าจริงอาร์เรย์คือหลายมิติ อื่นมันแบน เพียงสังเกตว่ามันเป็นเรื่องยากมากที่อาร์เรย์จะมีมิติที่แตกต่างกันเช่นถ้าคุณกำลังสร้างข้อมูลจากแบบจำลองมันจะมีโครงสร้างหลายมิติหรือแบนแบบเดียวกันที่สามารถวนลูปได้ หากไม่เป็นเช่นนั้นคุณต้องสร้างเองด้วยมือซึ่งหมายความว่าคุณรู้ว่าทุกอย่างจะอยู่ที่ไหนและใช้งานได้โดยไม่ต้องเขียนอัลกอริทึมแบบวนซ้ำ
array_shift()
เนื่องจากจะลบองค์ประกอบแรกและรีเซ็ตคีย์ตัวเลข! ควรใช้งานได้ดีกว่าcurrent()
ถ้ายังคงคันไว้สำหรับซับเดียว
นอกจากคำตอบก่อนหน้าและขึ้นอยู่กับสคีมาของอาร์เรย์ที่คุณต้องการตรวจสอบ:
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;
}
มันง่ายเหมือน
$isMulti = !empty(array_filter($array, function($e) {
return is_array($e);
}));
$is_multi_array = array_reduce(array_keys($arr), function ($carry, $key) use ($arr) { return $carry && is_array($arr[$key]); }, true);
นี่คือหนึ่งซับที่ดี มันวนซ้ำทุกปุ่มเพื่อตรวจสอบว่าค่าที่คีย์นั้นเป็นอาร์เรย์หรือไม่ สิ่งนี้จะทำให้มั่นใจได้ว่าเป็นจริง
if($array[0]){
//enter your code
}
if (isset($array[0])) { }
ในการใช้งานน้อย หากคุณแน่ใจว่าดัชนีของอาร์เรย์เริ่มต้นจาก 0
if ( array_key_exists(0,$array) ) {
// multidimensional array
} else {
// not a multidimensional array
}
* เฉพาะอาร์เรย์เหล่านั้นที่มีดัชนีตัวเลข
ฟังก์ชัน print_r ดั้งเดิมส่งคืนสตริงที่มนุษย์สามารถอ่านได้ เพียงนับอินสแตนซ์ "Array"
ลอง...
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 ใช้เวลา 0.83681297302246 วินาทีใน 500,000 ครั้ง"
มารยาท: Ruach HaKodesh
function isMultiArray(array $value)
{
return is_array(reset($value));
}
is_array($arr[key($arr)]);
ไม่มีลูปธรรมดาและเรียบง่าย
ทำงานร่วมกับอาเรย์ร่วมไม่เพียง แต่อาร์เรย์ที่เป็นตัวเลขซึ่งไม่สามารถมี 0 (เช่นในตัวอย่างก่อนหน้านี้จะทำให้คุณได้รับคำเตือนหากอาเรย์ไม่มี 0)