Як я можу імпладувати масив, пропускаючи пусті елементи масиву?


94

Perl join()ігнорує (пропускає) порожні значення масиву; PHP implode()не відображається.

Припустимо, у мене є масив:

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

врожайність:

one---four--six

замість (переважно IMHO):

one-four-six

Будь-яка інша вбудована поведінка, яку я шукаю? Або це буде нестандартна робота?


2
Ви помиляєтесь у поведінці Перла. 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,буде робити порожні рядки.
ікегамі

Відповіді:


210

Ви можете використовувати array_filter():

Якщо зворотний дзвінок не надається, всі записи вхідного сигналу, рівні FALSE(див. Перетворення на булеві ), будуть видалені.

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

Очевидно, це не спрацює, якщо у вас є 0(або будь-яке інше значення, яке оцінюється false) у своєму масиві, і ви хочете його зберегти. Але тоді ви можете надати власну функцію зворотного дзвінка.


5
Це означало б це false, а 0також їх викидають?
Бен,

1
@maz: Так, але ви завжди можете надати власний зворотний дзвінок. empty, як ви його використовуєте, також буде розглядатись 0і falseяк false(і видаляти) btw.
Фелікс Клінг

3
+1, але це повинно бути сказано, що з array_filter()допомогою фільтрів по замовчуванням вимкнено кожен false, nullпорожній рядок ( "") та 0.
Tadeck

1
@Tadeck: Так, просто перейдіть за посиланням у цитаті. Ще більше значень розглядаються як false: порожній масив 0.0та "0".
Фелікс Клінг

@Felix: Я це знав - просто хотів наголосити на цьому для людей, нових у PHP;) У всякому разі: дякую
Тадек

9

Припускаю, ви не можете вважати його вбудованим (оскільки функція працює з визначеною користувачем функцією), але ви завжди можете використовувати array_filter .
Щось на зразок:

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

1
Використання emptyмає такий самий ефект, як взагалі відсутність зворотного виклику. Редагувати: повернути значення потрібно заперечувати. Інакше будуть повернуті лише порожні елементи;) (фактично використання, emptyяк ви робили раніше, теж було неправильним)
Фелікс Клінг

1
Так, це відстало. Але ти дав мені правильну ідеюimplode('-', array_filter($ary, create_function('$a', 'return $a!="";')));
Том Оже,

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

Спробуйте це:

$result = array();

foreach($array as $row) { 
   if ($row != '') {
   array_push($result, $row); 
   }
}

implode('-', $result);


-1

array_fileter() здається, тут прийнятий спосіб, і, мабуть, все ще є найбільш надійною відповіддю tbh.

Однак наступне також буде спрацьовувати, якщо ви зможете гарантувати, що символу "клею" вже не існує в рядках кожного елемента масиву (що було б задано в більшості практичних обставин - інакше ви не зможете розрізнити клей з фактичних даних у масиві):

$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вирішує будь-яку проблему оригінальної публікації?
Том Ожер

1
Це не рішення. Передача в (масив) не видаляє порожні елементи з масиву.
mjwunderlich
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.