หลังจาก array_filter () ฉันจะรีเซ็ตคีย์ให้ไปตามลำดับตัวเลขเริ่มต้นที่ 0 ได้อย่างไร


108

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

ฉันจะรีเซ็ตดัชนีของอาร์เรย์ได้อย่างง่ายดายโดยเริ่มต้นที่ 0 และไปตามลำดับในอาร์เรย์ใหม่แทนที่จะเก็บดัชนีเก่าไว้



เว้นแต่คุณจะแน่ใจจริงๆว่าคุณไม่มีค่าว่าง / ศูนย์ ish / เท็จในอาร์เรย์ของคุณฉันต้องขอไม่ให้คุณใช้array_filter()- คุณอาจล้างมากกว่าที่คุณตั้งใจจะทำ นี่คือคำอธิบายบางส่วนพร้อมการสาธิต: stackoverflow.com/a/43657056/2943403
mickmackusa

คำตอบ:


224

หากคุณเรียกarray_valuesใช้อาร์เรย์ของคุณอาร์เรย์จะถูกจัดทำดัชนีใหม่จากศูนย์


ลิงก์ไม่ทำงานอีกต่อไปให้ใช้php.net/manual/en/function.array-values.phpแทน ฉันไม่สามารถอัปเดตได้เนื่องจากต้องเปลี่ยนตัวอักษรอย่างน้อย 6 ตัว
ราสมูสแฮนเซน

37

หากคุณใช้ Array filter ให้ทำดังนี้

$NewArray = array_values(array_filter($OldArray));

3
โอ้เวลาที่ฉันสูญเสียความพยายามที่จะคิดว่าทำไมผลลัพธ์ของ json_encode อาร์เรย์จึงแตกต่างจาก json_encode อาร์เรย์อาร์เรย์ที่กรอง ... ขอบคุณมาก ...
Jerther

13

ฉันกังวลว่ามีโปรแกรมเมอร์กี่คนที่คัดลอก / วางarray_values(array_filter())วิธีการลงในรหัสโดยบริสุทธิ์ใจ - ฉันสงสัยว่ามีโปรแกรมเมอร์กี่คนที่ประสบปัญหาโดยไม่รู้ตัวเนื่องจากความโลภของ array_filter หรือแย่กว่านั้นมีกี่คนที่ไม่เคยค้นพบว่าฟังก์ชันนี้ล้างค่าออกจากอาร์เรย์มากเกินไป ...

ฉันจะนำเสนอทางเลือกที่ดีกว่าสำหรับกระบวนการลอกNULLองค์ประกอบสองส่วนจากอาร์เรย์และจัดทำดัชนีคีย์ใหม่

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

$array=['foo',NULL,'bar',0,false,null,'0',''];

ค่า Null จะถูกลบออกโดยไม่คำนึงถึงตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็ก

แต่ดูสิ่งที่ยังคงอยู่ในอาร์เรย์เมื่อเราใช้array_values ​​() & array_filter () :

array_values(array_filter($array));

อาร์เรย์เอาต์พุต ($ array):

array (
  0 => 'foo',
  1 => 'bar'
)
// All empty, zero-ish, falsey values were removed too!!!

ตอนนี้ดูสิ่งที่คุณได้รับจากวิธีการของฉันที่ใช้array_walk () & is_null ()เพื่อสร้างอาร์เรย์ที่กรองใหม่:

array_walk($array,function($v)use(&$filtered){if(!is_null($v)){$filtered[]=$v;}});

สามารถเขียนทับได้หลายบรรทัดเพื่อให้อ่าน / อธิบายได้ง่ายขึ้น:

array_walk(                      // iterate each element of an input array
    $array,                      // this is the input array
    function($v)use(&$filtered){ // $v is each value, $filter (output) is declared/modifiable
        if(!is_null($v)){        // this literally checks for null values
            $filtered[]=$v;      // value is pushed into output with new indexes
        }
    }
);

อาร์เรย์เอาต์พุต (ตัวกรอง $):

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => false,
  4 => '0',
  5 => '',
)

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



ในทำนองเดียวกันหากคุณต้องการลบองค์ประกอบว่างเปล่าเท็จและว่าง (การเก็บค่าศูนย์) สี่วิธีนี้จะใช้ได้ผล:

var_export(array_values(array_diff($array,[''])));

หรือ

var_export(array_values(array_diff($array,[null])));

หรือ

var_export(array_values(array_diff($array,[false])));

หรือ

var_export(array_values(array_filter($array,'strlen')));

เอาท์พุต:

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => '0',
)

สุดท้ายสำหรับใครก็ตามที่ชอบไวยากรณ์ของโครงสร้างภาษาคุณยังสามารถพุชค่าที่มีคุณสมบัติเหมาะสมลงในอาร์เรย์ใหม่เพื่อสร้างดัชนีใหม่ได้

$array=['foo', NULL, 'bar', 0, false, null, '0', ''];

$result = [];
foreach ($array as $value) {
    if (strlen($value)) {
        $result[] = $value;
    }
}

var_export($result);

2
สิ่งต่าง ๆ จะไม่เป็นไปตามที่คาดไว้ถ้าคุณเขียนarray_values(array_filter($arr, function($el) {return $el !== '';}))? ดูเหมือนว่าวิธีธรรมชาติในการทำสิ่งที่ OP กำลังถามถึง
Casey

1
ใช่. ประเด็นของฉันคือนักพัฒนาควรหลีกเลี่ยงการกระตุ้นให้ใช้พฤติกรรมเริ่มต้นarray_filter()เว้นแต่ความรู้ที่ใกล้ชิดเกี่ยวกับข้อมูลจะอนุญาตให้กรองแบบโลภโดยไม่มีผลข้างเคียง (ข้อควรระวังเพิ่มเติม: empty()ทำงานในรูปแบบเดียวกันนี้และรวมถึงอาร์เรย์ว่างเปล่าด้วยความ
โลภ

2
คำตอบนี้ตอบคำถามที่แตกต่างกันโดยสิ้นเชิงโดยไม่เกี่ยวข้องกับคำถามเดิมไม่ว่าจะด้วยวิธีใดรูปร่างหรือรูปแบบใด ๆ
AnrDaemon

1
array_filter()ทำงานเหมือนที่คุณคาดหวังตามที่ระบุไว้ในคู่มือ: php.net/manual/en/function.array-filter.php "หากไม่มีการเรียกกลับรายการอาร์เรย์ทั้งหมดจะเท่ากับ FALSE (ดูการแปลงเป็นบูลีน ) จะถูกลบออก " และควรเป็นความรู้ทั่วไปในหมู่โปรแกรมเมอร์ PHP ว่า 0, null, false, '' และ '0' ทั้งหมดประเมินเป็นเท็จเมื่อบังคับให้บูลีน
madsen

1
สิ่งนี้คือคนส่วนใหญ่ไม่รู้ว่าจะเกิดอะไรขึ้น คุณทำฉันทำ แต่หลายคนไม่ทำ ฉันโพสต์คำตอบนี้เพื่อช่วยคนที่ไม่รู้
mickmackusa

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.