ฉันจะระเบิดอาร์เรย์ในขณะที่ข้ามรายการอาร์เรย์ว่างได้อย่างไร


98

Perl join()ไม่สนใจ (ข้าม) ค่าอาร์เรย์ว่าง PHP implode()ไม่ปรากฏ

สมมติว่าฉันมีอาร์เรย์:

$array = array('one', '', '', 'four', '', 'six');
implode('-', $array);

ผลตอบแทน:

one---four--six

แทนที่จะเป็น (IMHO เป็นที่ต้องการ):

one-four-six

มีตัวอื่นที่มีพฤติกรรมที่ฉันกำลังมองหาอยู่หรือไม่? หรือว่าจะเป็น jobbie ที่กำหนดเอง?


2
คุณผิดเกี่ยวกับพฤติกรรมของ Perl joinไม่ข้ามองค์ประกอบที่ไม่ได้กำหนด ในความเป็นจริงพวกเขาส่งผลให้เกิดการเตือน $a[0]="a"; $a[2]="c"; say join "-",@a;แสดงUse of uninitialized value within @a in join or stringและa--c. สามารถใช้join '-', grep !defined, ...เพื่อข้ามค่าที่ไม่ได้กำหนด grep !length,จะทำสตริงว่าง
ikegami

คำตอบ:


214

คุณสามารถใช้array_filter():

หากไม่มีการเรียกกลับรายการอินพุตทั้งหมดที่เท่ากับFALSE(ดูการแปลงเป็นบูลีน ) จะถูกลบออก

implode('-', array_filter($array));

เห็นได้ชัดว่าสิ่งนี้จะใช้ไม่ได้ถ้าคุณมี0(หรือค่าอื่น ๆ ที่ประเมินถึงfalse) ในอาร์เรย์ของคุณและคุณต้องการเก็บไว้ แต่คุณสามารถให้ฟังก์ชันโทรกลับของคุณเองได้


5
นั่นหมายความว่าอย่างfalseนั้นและ0ถูกโยนออกไปด้วยหรือไม่?
เบ็น

1
@maz: ใช่ แต่คุณสามารถโทรกลับได้ตลอดเวลา emptyในขณะที่คุณใช้มันจะปฏิบัติ0และfalseเป็นfalse(และลบ) btw ด้วย
Felix Kling

3
+1 แต่มันจะต้องมีการกล่าวว่าarray_filter()โดยตัวกรองเริ่มต้นออกทุกfalse, nullสตริงว่าง ( '') 0และ
Tadeck

1
@Tadeck: ใช่เพียงไปตามลิงค์ในใบเสนอราคา ค่าที่มากกว่านั้นถือเป็นfalseอาร์เรย์ว่าง0.0และ"0".
Felix Kling

@Felix: ฉันรู้แล้ว - แค่อยากจะเน้นให้คนใหม่ใน PHP;) อย่างไรก็ตาม: ขอบคุณ
Tadeck

9

ฉันคิดว่าคุณไม่สามารถคิดว่ามันสร้างขึ้นใน (เพราะฟังก์ชั่นการทำงานที่มีการใช้ฟังก์ชั่นที่กำหนดไว้) แต่คุณก็สามารถใช้array_filter
สิ่งที่ต้องการ:

function rempty ($var)
{
    return !($var == "" || $var == null);
}
$string = implode('-',array_filter($array, 'rempty'));

1
การใช้emptyมีผลเช่นเดียวกับการไม่โทรกลับเลย แก้ไข: คุณต้องลบล้างค่าที่ส่งคืน มิฉะนั้นจะส่งคืนเฉพาะองค์ประกอบที่ว่างเปล่า) (การใช้จริงemptyอย่างที่คุณทำก่อนหน้านี้ก็ผิดเช่นกัน)
Felix Kling

1
ใช่ว่าย้อนหลัง แต่คุณให้ความคิดที่ถูกต้องแก่ฉันimplode('-', array_filter($ary, create_function('$a', 'return $a!="";')));
Tom Auger

3

คุณควรใช้ตัวกรองอย่างไรขึ้นอยู่กับสิ่งที่คุณเห็นว่า "ว่างเปล่า" เท่านั้น

function my_filter($item)
{
    return !empty($item); // Will discard 0, 0.0, '0', '', NULL, array() of FALSE
    // Or...
    return !is_null($item); // Will only discard NULL
    // or...
    return $item != "" && $item !== NULL; // Discards empty strings and NULL
    // or... whatever test you feel like doing
}

function my_join($array)
{
    return implode('-',array_filter($array,"my_filter"));
} 

3

ในการลบnull, false, emptyสตริง แต่รักษา0ฯลฯ ใช้ func ' strlen'

$arr = [null, false, "", 0, "0", "1", "2", "false"];
print_r(array_filter($arr, 'strlen'));

จะส่งออก:

//Array ( [3] => 0 [4] => 0 [5] => 1 [6] => 2 [7] => false )

1

จากสิ่งที่ฉันหาได้ฉันบอกว่ามีโอกาสไม่มีวิธีใดเลยที่จะใช้ PHP ในตัวสำหรับสิ่งนั้น แต่คุณอาจทำอะไรบางอย่างตามแนวนี้:

function implode_skip_empty($glue,$arr) {
      $ret = "";
      $len = sizeof($arr);
      for($i=0;$i<$len;$i++) {
          $val = $arr[$i];    
          if($val == "") {
              continue;
          } else {
            $ret .= $arr.($i+1==$len)?"":$glue;
          }
      }
      return $ret;
}



-1

array_fileter() ดูเหมือนจะเป็นวิธีที่ได้รับการยอมรับที่นี่และอาจเป็นคำตอบที่มีประสิทธิภาพมากที่สุด

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

$array = array('one', '', '', 'four', '', 'six');
$str   = implode('-', $array);
$str   = preg_replace ('/(-)+/', '\1', $str);

-3

ลองสิ่งนี้:

if(isset($array))  $array = implode(",", (array)$array);

คุณอาจต้องการใช้ isset () เพื่อป้องกันคำเตือน
user2775080

ฉันไม่แน่ใจว่าจะแคสต์isset()อาร์เรย์อินพุตอย่างไรเพื่อarrayแก้ไขข้อกังวลของโพสต์ต้นฉบับ
Tom Auger

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