ลบองค์ประกอบอาร์เรย์ที่ว่างเปล่า


783

องค์ประกอบบางอย่างในอาเรย์ของฉันเป็นสตริงว่างขึ้นอยู่กับสิ่งที่ผู้ใช้ส่ง ฉันต้องการลบองค์ประกอบเหล่านั้น ฉันมีสิ่งนี้:

foreach($linksArray as $link)
{
    if($link == '')
    {
        unset($link);
    }
}
print_r($linksArray);

แต่มันไม่ทำงาน $linksArrayยังคงมีองค์ประกอบที่ว่างเปล่า ฉันได้ลองทำด้วยempty()ฟังก์ชั่นแล้ว แต่ผลลัพธ์ก็เหมือนกัน


1
ฉันคิดว่ามันคุ้มค่าที่จะกล่าวถึงว่าโค้ดข้างต้นใช้งานไม่ได้เพราะ unset (... ) ทำงานกับตัวแปรที่สร้างโดยลูป foreach ไม่ใช่อาเรย์ดั้งเดิมที่เห็นได้ชัดเหมือนอยู่ก่อนลูป
saveario

if (! empty ($ link)) {echo $ link; } สิ่งนี้ใช้ได้กับฉัน
Shiplu

คุณกำลังเปลี่ยนลิงก์ $ ที่ไม่มีการอ้างอิง! ใช้ foreach ($ linksArray เป็น $ key => $ link) unset (linksArray [$ key])
TD_Nijboer

คำตอบ:


1547

ในขณะที่คุณกำลังจัดการกับอาเรย์ของสตริงคุณสามารถใช้งานarray_filter()ได้ซึ่งจัดการสิ่งเหล่านี้ให้คุณได้อย่างสะดวก:

print_r(array_filter($linksArray));

โปรดทราบว่าหากไม่มีการโทรกลับรายการใด ๆ ของอาร์เรย์จะเท่ากับFALSE(ดูการแปลงเป็นบูลีน ) จะถูกลบออก ดังนั้นหากคุณต้องการรักษาองค์ประกอบที่เป็นสตริงที่แน่นอน'0'คุณจะต้องมีการติดต่อกลับที่กำหนดเอง:

// PHP 7.4 and later
print_r(array_filter($linksArray, fn($value) => !is_null($value) && $value !== ''));

// PHP 5.3 and later
print_r(array_filter($linksArray, function($value) { return !is_null($value) && $value !== ''; }));

// PHP < 5.3
print_r(array_filter($linksArray, create_function('$value', 'return $value !== "";')));

16
array_filterควรลบองค์ประกอบที่ว่างเปล่า และถ้าคำจำกัดความว่างเปล่าของ PHP ไม่เหมือนกับคำจำกัดความของคุณคุณสามารถกรอกตัวเลือกการโทรกลับด้วยฟังก์ชั่นที่ไม่ระบุชื่อซึ่งจะกำจัดองค์ประกอบที่ไม่ต้องการ เห็นได้ชัดว่าคุณต้องมี php 5.3 หรือใหม่กว่าเพื่อใช้การโทรกลับที่ไม่ระบุชื่อ stackoverflow.com/questions/2412299/…
Buttle Butkus

76
ระวัง array_filter ไม่ทำดัชนีดัชนีอาร์เรย์อีกครั้ง (ปัญหาอาจเกิดขึ้นในการใช้อาร์เรย์กระบวนการในคำสั่ง) ดังนั้นห่อทั้งหมดด้วยฟังก์ชัน array_values
Michal - wereda-net

8
คำตอบไม่ถูกต้องเพราะมันจะลบfalseองค์ประกอบด้วย ( php.net/manual/en/function.array-filter.php )
pliashkou

5
@Deji คุณลองพิมพ์อาร์เรย์นั้นก่อนที่จะกรองหรือไม่ ฉันคิดว่าการตั้งค่าaเป็นครั้งที่สองจะเป็นการรีเซ็ตครั้งแรก
Cullub

5
@Cranio: ซึ่งถูกครอบคลุมโดยความคิดเห็นอื่นแล้ว มันไม่ถูกต้อง แต่อาจกว้างกว่าความต้องการของคุณ นั่นไม่ได้หมายความว่าคนอื่นไม่สามารถหาได้ว่าเป็นประโยชน์ ท้ายที่สุดถ้าคุณมีสายอักขระอยู่ในอาร์เรย์คำตอบนี้จะลบเฉพาะสตริงที่ว่างเปล่า
Martijn Pieters

169

คุณสามารถใช้array_filterเพื่อลบองค์ประกอบที่ว่างเปล่า:

$emptyRemoved = array_filter($linksArray);

หากคุณมี(int) 0อาเรย์ของคุณคุณอาจใช้สิ่งต่อไปนี้:

$emptyRemoved = remove_empty($linksArray);

function remove_empty($array) {
  return array_filter($array, '_remove_empty_internal');
}

function _remove_empty_internal($value) {
  return !empty($value) || $value === 0;
}

แก้ไข:บางทีองค์ประกอบของคุณไม่ว่างเปล่าต่อ se แต่มีช่องว่างอย่างน้อยหนึ่งช่อง ... คุณสามารถใช้สิ่งต่อไปนี้ก่อนที่จะใช้array_filter

$trimmedArray = array_map('trim', $linksArray);

10
ฉันเพิ่งเพิ่มไปยังคำตอบที่ยอมรับโดย BoltClock คุณสามารถทำได้ array_filter ($ foo, 'strlen') เพื่อหลีกเลี่ยงปัญหา "0" และลบเฉพาะที่มีความยาวเป็นศูนย์
AB Carroll

2
@nezZario: สมมติว่าคุณมีscalarรายการในอาร์เรย์ของคุณใช่ มิฉะนั้นคุณไม่สามารถทำเช่นนั้นได้
Andrew Moore

2
ใช้แลมบ์ดาสำหรับ php> = 5.3function remove_empty($array) { return array_filter($array, function($value){return !empty($value) || $value === 0;}); }
Viral

1
array_map()ฉันใช้เวทย์มนตร์เพราะมีช่องว่างในอาร์เรย์ที่ว่างเปล่าเหล่านั้นหรือไม่!
มหัศจรรย์

126

คำตอบที่ได้รับความนิยมมากที่สุดในหัวข้อนี้คือ INCORRECT อย่างแน่นอน

พิจารณาสคริปต์ PHP ต่อไปนี้:

<?php
$arr = array('1', '', '2', '3', '0');
// Incorrect:
print_r(array_filter($arr));
// Correct:
print_r(array_filter($arr, 'strlen'));

ทำไมนี้ เนื่องจากสตริงที่มีอักขระ '0' ตัวเดียวจะประเมินว่าเป็นบูลีนเท็จดังนั้นแม้ว่าจะไม่ใช่สตริงที่ว่างเปล่า แต่ก็ยังคงได้รับการกรอง นั่นจะเป็นข้อผิดพลาด

ผ่านฟังก์ชั่น strlen ในตัวในขณะที่ฟังก์ชั่นการกรองจะทำงานได้เพราะมันจะส่งกลับจำนวนเต็มไม่เป็นศูนย์สำหรับสตริงที่ไม่ว่างเปล่าและจำนวนเต็มศูนย์สำหรับสตริงว่าง จำนวนเต็มที่ไม่เป็นศูนย์จะประเมินเป็นจริงเสมอเมื่อแปลงเป็นบูลีนในขณะที่เลขศูนย์จะประเมินเป็นเท็จเสมอเมื่อแปลงเป็นบูลีน

ดังนั้นคำตอบที่ถูกต้องแน่นอนและชัดเจนคือ:

$arr = array_filter($arr, 'strlen');

3
ตกลง นี่ควรเป็นคำตอบที่ยอมรับได้สำหรับผู้ที่อาร์เรย์มีสตริง
mwieczorek

2
upvoted คำตอบที่ดีกว่าคำตอบอื่น ๆ อีกมากมายอย่างไรก็ตามควรสังเกตว่าคำตอบที่ได้รับการยอมรับในปัจจุบันนั้นในทางเทคนิคแล้วไม่ถูกต้องเนื่องจาก "empty" นั้นมีความหมายพิเศษภายใน PHP (ค่าบางอย่างที่มีคุณสมบัติเป็น "ว่างเปล่า": 0, "", null)
rinogo

5
มันไม่ถูกต้องมันเกี่ยวกับบริบท ในบางกรณีการรักษาค่า 0 อาจมีความสำคัญ ดังนั้นโปรดอย่าพูดว่าทุกคนผิดยกเว้นคุณ
Macr1408

6
สิ่งนี้จะหยุดพักหากอาร์เรย์มีอาร์เรย์อื่น:strlen() expects parameter 1 to be string, array given
hpaknia

คุณสามารถพูดได้ว่านี่อาจเป็นวิธีการที่ดี (แทนที่จะบอกว่าคนอื่นไม่ถูกต้อง) เพื่อให้บรรลุการกระทำที่ต้องการโดยทั่วไปแล้วไม่ใช่ทุกกรณีที่คล้ายกันแม้ว่าวิธีนี้จะใช้ได้กับกรณีของฉันก็ตาม
MR_AMDEV

102
$linksArray = array_filter($linksArray);

"ถ้าไม่มีการโทรกลับรายการอินพุตทั้งหมดที่มีค่าเป็น FALSE จะถูกลบ" - http://php.net/manual/th/function.array-filter.php


4
ฉันลองทำสิ่งนี้หลังจากที่ Google กำลังพบปัญหา น่าเสียดายที่มันทิ้งองค์ประกอบที่ว่างเปล่าไว้สำหรับฉัน
จะ

18
สิ่งนี้จะลบ '0'
OIS

2
@ Will: คุณแน่ใจเหรอ? มันยังลบสตริงว่าง ๆ ฉันทดสอบมันสำเร็จ บางทีค่าอินพุตของคุณอาจมีช่องว่างและควรถูกตัดออกก่อน ตามกฎการแปลงบูลีนสตริงว่างจะถูกประเมินเป็นเท็จและดังนั้นจึงถูกลบโดย array_filter
acme


42

คุณสามารถทำได้

array_filter($array)

array_filter: "ถ้าไม่มีการโทรกลับรายการอินพุตทั้งหมดที่เท่ากับ FALSE จะถูกลบ" ซึ่งหมายความว่าองค์ประกอบที่มีค่า NULL, 0, '0', '', FALSE, array () จะถูกลบเช่นกัน

ตัวเลือกอื่นกำลังทำ

array_diff($array, array(''))

ซึ่งจะลบองค์ประกอบที่มีค่า NULL, '' และ FALSE

หวังว่าจะช่วย :)

UPDATE

นี่คือตัวอย่าง

$a = array(0, '0', NULL, FALSE, '', array());

var_dump(array_filter($a));
// array()

var_dump(array_diff($a, array(0))) // 0 / '0'
// array(NULL, FALSE, '', array());

var_dump(array_diff($a, array(NULL))) // NULL / FALSE / ''
// array(0, '0', array())

เพื่อสรุป:

  • 0 หรือ '0' จะลบ 0 และ '0'
  • NULL, FALSE หรือ '' จะลบ NULL, FALSE และ ''

36
foreach($linksArray as $key => $link) 
{ 
    if($link === '') 
    { 
        unset($linksArray[$key]); 
    } 
} 
print_r($linksArray); 

4
กระชับ, การแก้ปัญหาที่สามารถอ่านได้และปลอดภัยที่ไม่ได้ลบและfalse 0เมื่อพิจารณาว่ามีการโพสต์ในนาทีเดียวกับคำตอบที่ยอมรับ (ไม่ปลอดภัยและไม่ถูกต้อง) ฉันสามารถสรุปได้ 8 upvotes ของคุณเมื่อเทียบกับคำตอบที่ยอมรับ 649 ลงไปเป็นคำตอบเดียว
rybo111

@ rybo111 - อาจเป็นไปได้ว่าการใช้ตรรกะนั้นในการโทรกลับเพื่อarray_filter()เป็นวิธีที่สะอาดกว่าการforeach()วนซ้ำ
Mark Baker

อาจเร็วกว่า แต่วิธีแก้ปัญหาของคุณอ่านง่ายที่สุดซึ่งเป็นสิ่งสำคัญ สำหรับผู้ที่ต้องการใช้โซลูชันของคุณtrim()ฉันขอแนะนำif(is_string($link) && trim($link) === '')
rybo111

33

อีกหนึ่งสายการบินเพื่อลบองค์ประกอบที่ว่างเปล่า ("" สตริงว่าง) จากอาร์เรย์ของคุณ

$array = array_filter($array, function($a) {return $a !== "";});

หมายเหตุ: รหัสนี้จงใจช่วยnull, 0และfalseองค์ประกอบ


หรือบางทีคุณต้องการตัดองค์ประกอบอาร์เรย์ของคุณก่อน:

$array = array_filter($array, function($a) {
    return trim($a) !== "";
});

หมายเหตุ: รหัสนี้ยังลบnullและfalseองค์ประกอบ


3
สิ่งที่ฉันต้องการและนี่ก็เข้ากันได้กับPHPs รุ่นเก่าด้วยขอบคุณ! ;-)
Stano

1
@ JohnK ผิด การทำเช่นนี้เหมือน whants ผู้ใช้สามารถเรียกกลับเป็นสิ่งจำเป็นถ้าคุณต้องการที่จะลบ alzo เลขศูนย์และค่า falsey อื่น ๆ
Cranio

โอ้ ... นี่ช่างน่ารักจริงๆ ควรเป็นที่ยอมรับ
Henrik Petterson

20

ในระยะสั้น:

นี่คือรหัสที่ฉันแนะนำ:

$myarray =  array_values(array_filter(array_map('trim', $myarray), 'strlen'));

คำอธิบาย:

ฉันคิดว่าการใช้array_filterเป็นสิ่งที่ดี แต่ไม่เพียงพอเพราะคุณค่าเป็นเหมือนspaceและ\n... เก็บไว้ในอาร์เรย์และมักจะไม่ดี

ดังนั้นผมจึงขอแนะนำให้คุณใช้ส่วนผสม และarray_filterarray_map

array_mapสำหรับการตัดแต่งใช้array_filterสำหรับลบค่าว่างเปล่าใช้strlenสำหรับเก็บ0ค่าและarray_valuesสำหรับการทำดัชนีใหม่หากคุณต้องการ

ตัวอย่าง:

$myarray = array("\r", "\n", "\r\n", "", " ", "0", "a");

// "\r", "\n", "\r\n", " ", "a"
$new1 = array_filter($myarray);

// "a"
$new2 = array_filter(array_map('trim', $myarray));

// "0", "a"
$new3 = array_filter(array_map('trim', $myarray), 'strlen');

// "0", "a" (reindex)
$new4 = array_values(array_filter(array_map('trim', $myarray), 'strlen'));

var_dump($new1, $new2, $new3, $new4);

ผล:

array(5) {
  [0]=>
" string(1) "
  [1]=>
  string(1) "
"
  [2]=>
  string(2) "
"
  [4]=>
  string(1) " "
  [6]=>
  string(1) "a"
}
array(1) {
  [6]=>
  string(1) "a"
}
array(2) {
  [5]=>
  string(1) "0"
  [6]=>
  string(1) "a"
}
array(2) {
  [0]=>
  string(1) "0"
  [1]=>
  string(1) "a"
}

แบบทดสอบออนไลน์:

http://phpio.net/s/5yg0


13

หากคุณกำลังทำงานกับอาเรย์ตัวเลขและต้องการสร้างดัชนีอาเรย์ใหม่หลังจากลบองค์ประกอบที่ว่างเปล่าให้ใช้ฟังก์ชันarray_values :

array_values(array_filter($array));

ดูเพิ่มเติมที่: อาร์เรย์ PHP ดัชนี?


12

คำตอบที่โหวตมากที่สุดนั้นผิดหรืออย่างน้อยก็ไม่จริงทั้งหมดเนื่องจาก OP กำลังพูดถึงสตริงที่ว่างเปล่าเท่านั้น นี่คือคำอธิบายอย่างละเอียด:

อะไรที่ว่างเปล่าหมายถึง?

ก่อนอื่นเราต้องเห็นด้วยกับความหมายที่ว่างเปล่า คุณหมายถึงการกรอง:

  1. สตริงที่ว่างเปล่าเท่านั้น ( "")?
  2. เท็จอย่างเคร่งครัดค่า? ( $element === false)
  3. falseyค่า? (เช่น 0, 0.0, "", "0", NULL, array () ... )
  4. เทียบเท่ากับempty()ฟังก์ชันของ PHP หรือไม่

คุณจะกรองค่าอย่างไร

หากต้องการกรองสตริงว่างเท่านั้น :

$filtered = array_diff($originalArray, array(""));

หากต้องการกรองเฉพาะค่าเท็จอย่างเคร่งครัดคุณต้องใช้ฟังก์ชันการโทรกลับ :

$filtered = array_diff($originalArray, 'myCallback');
function myCallback($var) {
    return $var === false;
}

การเรียกกลับยังมีประโยชน์สำหรับชุดค่าผสมที่คุณต้องการกรองค่า "falsey" ยกเว้นบางค่า (ตัวอย่างเช่นกรองทุกรายการnullและfalseอื่น ๆ ออกจากรายการเท่านั้น0):

$filtered = array_filter($originalArray, 'myCallback');
function myCallback($var) {
    return ($var === 0 || $var === '0');
}

กรณีที่สามและสี่คือ (เพื่อจุดประสงค์ของเราในที่สุด) และสำหรับสิ่งที่คุณต้องใช้คือค่าเริ่มต้น:

$filtered = array_filter($originalArray);

2
หากคุณต้องการที่จะออกnullและfalseแต่ออกจาก 0 คุณยังสามารถใช้strlenฟังก์ชั่นในตัวของ PHP เป็นโทรกลับของคุณ
Cullub

10

ฉันต้องทำเช่นนี้เพื่อรักษาค่าอาร์เรย์ของ (สตริง) 0

$url = array_filter($data, function ($value) {
  return (!empty($value) || $value === 0 || $value==='0');
});





7

ฉันใช้สคริปต์ต่อไปนี้เพื่อลบองค์ประกอบว่างออกจากอาร์เรย์

for ($i=0; $i<$count($Array); $i++)
  {
    if (empty($Array[$i])) unset($Array[$i]);
  }

7

เพียงแค่ต้องการมีส่วนร่วมทางเลือกในการลูป ... ยังแก้ไขช่องว่างในคีย์ ...

ในกรณีของฉันฉันต้องการเก็บคีย์อาร์เรย์ตามลำดับเมื่อการดำเนินการเสร็จสมบูรณ์ (ไม่ใช่แค่เลขคี่ซึ่งเป็นสิ่งที่ฉันกำลังจ้องมองอยู่การตั้งค่ารหัสเพื่อค้นหาคีย์แปลก ๆ ดูเหมือนจะเปราะบางสำหรับฉันและไม่เป็นมิตรในอนาคต)

ฉันกำลังมองหาบางสิ่งที่เพิ่มเติมเช่นนี้: http://gotofritz.net/blog/howto/removing-empty-array-elements-php/

การรวมกันของ array_filter และ array_slice ทำเคล็ดลับ

$example = array_filter($example); $example = array_slice($example,0);

ไม่มีความคิดเกี่ยวกับประสิทธิภาพหรือมาตรฐาน แต่ใช้งานได้


ฉันคิดว่า array_values ​​จะมีผลลัพธ์เช่นเดียวกับ array_slice ดูเหมือนว่าจะเข้าใจได้ง่ายขึ้นในแง่ของการอ่านโค้ดในภายหลัง
arlomedia

6
$my = ("0"=>" ","1"=>"5","2"=>"6","3"=>" ");   

foreach ($my as $key => $value) {
    if (is_null($value)) unset($my[$key]);
}

foreach ($my as $key => $value) {
    echo   $key . ':' . $value . '<br>';
} 

เอาท์พุต

1: 5

2: 6



5

เพียงหนึ่งบรรทัด: อัปเดต (ขอบคุณ @suther):

$array_without_empty_values = array_filter($array);

ไม่ต้องการพารามิเตอร์ตัวที่สองของคุณ: $ clean_array = array_filter ($ dirty_array);
suther

4

ใช้array_filterฟังก์ชั่นเพื่อลบค่าว่าง:

$linksArray = array_filter($linksArray);
print_r($linksArray);

เขาต้องการลบสตริงว่างซึ่งไม่เท่ากับค่าว่าง
Cranio

4

ลบองค์ประกอบอาร์เรย์ที่ว่างเปล่า

function removeEmptyElements(&$element)
{
    if (is_array($element)) {
        if ($key = key($element)) {
            $element[$key] = array_filter($element);
        }

        if (count($element) != count($element, COUNT_RECURSIVE)) {
            $element = array_filter(current($element), __FUNCTION__);
        }

        return $element;
    } else {
        return empty($element) ? false : $element;
    }
}

$data = array(
    'horarios' => array(),
    'grupos' => array(
        '1A' => array(
            'Juan' => array(
                'calificaciones' => array(
                    'Matematicas' => 8,
                    'Español' => 5,
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => 20,
                    'febrero' => 10,
                    'marzo' => '',
                )
            ),
            'Damian' => array(
                'calificaciones' => array(
                    'Matematicas' => 10,
                    'Español' => '',
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => 20,
                    'febrero' => '',
                    'marzo' => 5,
                )
            ),
        ),
        '1B' => array(
            'Mariana' => array(
                'calificaciones' => array(
                    'Matematicas' => null,
                    'Español' => 7,
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => null,
                    'febrero' => 5,
                    'marzo' => 5,
                )
            ),
        ),
    )
);

$data = array_filter($data, 'removeEmptyElements');
var_dump($data);

มันได้ผล!


3

ตามวิธีการของคุณคุณสามารถจับองค์ประกอบเหล่านั้นในอาเรย์อื่นและใช้สิ่งที่ชอบดังนี้

foreach($linksArray as $link){
   if(!empty($link)){
      $new_arr[] = $link
   }
}

print_r($new_arr);

1

ลองสิ่งนี้ ** ** ตัวอย่าง

$or = array(
        'PersonalInformation.first_name' => $this->request->data['User']['first_name'],
        'PersonalInformation.last_name' => $this->request->data['User']['last_name'],
        'PersonalInformation.primary_phone' => $this->request->data['User']['primary_phone'],
        'PersonalInformation.dob' => $this->request->data['User']['dob'],
        'User.email' => $this->request->data['User']['email'],
    );



 $or = array_filter($or);

    $condition = array(
        'User.role' => array('U', 'P'),
        'User.user_status' => array('active', 'lead', 'inactive'),
        'OR' => $or
    );

1
นี่คืออะไร? มีคำตอบที่เกี่ยวข้องอื่น ๆ อีกมากมาย คุณจะเพิ่มอะไรที่นี่
Félix Gagnon-Grenier

ตรวจสอบ url คำถามที่นี่ !! / * ลบองค์ประกอบอาร์เรย์ว่างเปล่า * /
Ashish pathak

1

ฉันคิดว่าarray_walkเหมาะสมกว่านี้มาก

$linksArray = array('name', '        ', '  342', '0', 0.0, null, '', false);

array_walk($linksArray, function(&$v, $k) use (&$linksArray){
    $v = trim($v);
    if ($v == '')
        unset($linksArray[$k]);
});
print_r($linksArray);

เอาท์พุท:

Array
(
    [0] => name
    [2] => 342
    [3] => 0
    [4] => 0
)
  • เราตรวจสอบให้แน่ใจว่าค่าว่างถูกลบแม้ว่าผู้ใช้จะเพิ่มมากกว่าหนึ่งช่องว่าง
  • นอกจากนี้เรายังตัดพื้นที่ว่างเปล่าจากค่าที่ถูกต้อง

  • ในที่สุดเฉพาะ (null), (บูลีนเท็จ) และ ('') จะถือเป็นสตริงว่าง

ส่วนFalseเรื่องการลบออกนั้นเป็นเรื่องที่ทำได้เนื่องจาก AFAIK ผู้ใช้ไม่สามารถส่งค่าบูลีนได้


0

ด้วยสิ่งต่าง ๆ เหล่านี้จะเป็นการดีกว่าหากคุณมีความชัดเจนในสิ่งที่คุณต้องการและไม่ต้องการ

มันจะช่วยให้คนต่อไปที่จะไม่ถูกจับด้วยความประหลาดใจที่พฤติกรรมของarray_filter()โดยไม่ต้องโทรกลับ ตัวอย่างเช่นฉันลงเอยกับคำถามนี้เพราะฉันลืมถ้าarray_filter()ลบNULLหรือไม่ ฉันเสียเวลาเมื่อฉันสามารถใช้วิธีการแก้ปัญหาด้านล่างและได้รับคำตอบของฉัน

นอกจากนี้ตรรกะคือผู้ไม่เชื่อเรื่องภาษาในแง่ที่ว่ารหัสสามารถคัดลอกเป็นภาษาอื่นโดยไม่ต้องอยู่ภายใต้พฤติกรรมของฟังก์ชั่น PHP เช่นarray_filterเมื่อไม่มีการส่งกลับโทรกลับ

ในโซลูชันของฉันจะเห็นได้อย่างชัดเจนว่าเกิดอะไรขึ้น ลบเงื่อนไขเพื่อเก็บบางสิ่งหรือเพิ่มเงื่อนไขใหม่เพื่อกรองค่าเพิ่มเติม

ไม่ต้องสนใจการใช้งานจริงarray_filter()เนื่องจากฉันเพิ่งผ่านการติดต่อกลับแบบกำหนดเอง - คุณสามารถไปข้างหน้าและดึงข้อมูลนั้นออกไปยังฟังก์ชั่นของตัวเองได้หากคุณต้องการ ฉันแค่ใช้มันเป็นน้ำตาลเป็นforeachวง

<?php

$xs = [0, 1, 2, 3, "0", "", false, null];

$xs = array_filter($xs, function($x) {
    if ($x === null) { return false; }
    if ($x === false) { return false; }
    if ($x === "") { return false; }
    if ($x === "0") { return false; }
    return true;
});

$xs = array_values($xs); // reindex array   

echo "<pre>";
var_export($xs);

ข้อดีอีกประการของวิธีนี้คือคุณสามารถแยกการกรองภาคแสดงออกเป็นฟังก์ชันนามธรรมที่กรองค่าเดียวต่ออาร์เรย์และสร้างโซลูชันแบบเรียงซ้อน

ดูตัวอย่างนี้และความคิดเห็นแบบอินไลน์สำหรับผลลัพธ์

<?php

/**
 * @param string $valueToFilter
 *
 * @return \Closure A function that expects a 1d array and returns an array
 *                  filtered of values matching $valueToFilter.
 */
function filterValue($valueToFilter)
{
    return function($xs) use ($valueToFilter) {
        return array_filter($xs, function($x) use ($valueToFilter) {
            return $x !== $valueToFilter;
        });
    };
}

// partially applied functions that each expect a 1d array of values
$filterNull = filterValue(null);
$filterFalse = filterValue(false);
$filterZeroString = filterValue("0");
$filterEmptyString = filterValue("");

$xs = [0, 1, 2, 3, null, false, "0", ""];

$xs = $filterNull($xs);        //=> [0, 1, 2, 3, false, "0", ""]
$xs = $filterFalse($xs);       //=> [0, 1, 2, 3, "0", ""]
$xs = $filterZeroString($xs);  //=> [0, 1, 2, 3, ""]
$xs = $filterEmptyString($xs); //=> [0, 1, 2, 3]

echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]

ตอนนี้คุณสามารถสร้างฟังก์ชั่นที่เรียกว่าการfilterer()ใช้แบบไดนามิกpipe()ซึ่งจะใช้ฟังก์ชั่นที่ใช้บางส่วนเหล่านี้สำหรับคุณ

<?php

/**
 * Supply between 1..n functions each with an arity of 1 (that is, accepts
 * one and only one argument). Versions prior to php 5.6 do not have the
 * variadic operator `...` and as such require the use of `func_get_args()` to
 * obtain the comma-delimited list of expressions provided via the argument
 * list on function call.
 *
 * Example - Call the function `pipe()` like:
 *
 *   pipe ($addOne, $multiplyByTwo);
 *
 * @return closure
 */
function pipe()
{
    $functions = func_get_args(); // an array of callable functions [$addOne, $multiplyByTwo]
    return function ($initialAccumulator) use ($functions) { // return a function with an arity of 1
        return array_reduce( // chain the supplied `$arg` value through each function in the list of functions
            $functions, // an array of functions to reduce over the supplied `$arg` value
            function ($accumulator, $currFn) { // the reducer (a reducing function)
                return $currFn($accumulator);
            },
            $initialAccumulator
        );
    };
}

/**
 * @param string $valueToFilter
 *
 * @return \Closure A function that expects a 1d array and returns an array
 *                  filtered of values matching $valueToFilter.
 */
function filterValue($valueToFilter)
{
    return function($xs) use ($valueToFilter) {
        return array_filter($xs, function($x) use ($valueToFilter) {
            return $x !== $valueToFilter;
        });
    };
}

$filterer = pipe(
    filterValue(null),
    filterValue(false),
    filterValue("0"),
    filterValue("")
);

$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterer($xs);

echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.