Предыстория: Trevor работает с реализацией стандартного алгоритма PHP: возьмите основной набор пар значений по умолчанию и обновите эти пары имя-значение, но только для тех пар имя-значение, где действительно допустимое значение обновления действительно существует.
Проблема: по умолчанию PHP array_merge работает так: он перезапишет непустое значение пустым значением.
$aamain = Array('firstname'=>'peter','age'=>'32','nation'=>''); $update = Array('firstname' => '','lastname' => 'griffin', age =>'33','nation'=>'usa'); print_r(array_merge($aamain,$update)); /* Array ( [firstname] => // <-- update set this to blank, NOT COOL! [age] => 33 // <-- update set this to 33, thats cool [lastname] => griffin // <-- update added this key-value pair, thats cool [nation] => usa // <-- update filled in a blank, thats cool. ) */
Вопрос: Каков способ наименьших строк кода для массива array_merge, где пустые значения никогда не перезаписывают уже существующие значения?
print_r(array_coolmerge($aamain,$update)); /* Array ( [firstname] => peter // <-- don't blank out a value if one already exists! [age] => 33 [lastname] => griffin [nation] => usa ) */
UPDATE: 2016-06-17T11: 51: 54 вопрос был обновлен с уточняющим контекстом и переименовал переменные.
Ну, если вам нужен «умный» способ сделать это, вот оно, но это может быть не так легко читать, как просто делать цикл.
$merged = array_merge(array_filter($foo, 'strval'), array_filter($bar, 'strval'));
изменить: или использовать + …
Попробуй это:
$merged = array_map( create_function('$foo,$bar','return ($bar?$bar:$foo);'), $foobar,$feebar );
Не наиболее читаемое решение, но оно должно заменять только непустые значения, независимо от того, в каком порядке передаются массивы.
Отрегулируйте ваши потребности:
# Replace keys in $foo foreach ($foo as $key => $value) { if ($value != '' || !isset($bar[$key])) continue; $foo[$key] = $bar[$key]; } # Add other keys in $bar # Will not overwrite existing keys in $foo $foo += $bar;
array_replace_recursive($array, $array2);
Это решение.
Это приведет к дублированию в новый массив, я не знаю, действительно ли это то, что вы хотите.
<?php $foobar = Array('firstname' => 'peter','age' => '33',); $feebar = Array('firstname' => '','lastname' => 'griffin',); $merged=$foobar; foreach($feebar as $k=>$v){ if(isset($foobar[$k]))$merged[$k]=array($v,$foobar[$k]); else $merged[$k]=$v; } print_r($merged); ?>
Это просто заверит, что сборщик никогда не закроет значение в foobar:
<?php $foobar = Array('firstname' => 'peter','age' => '33',); $feebar = Array('firstname' => '','lastname' => 'griffin',); $merged=$foobar; foreach($feebar as $k=>$v) if($v)$merged[$k]=$v; print_r($merged); ?>
или, конечно,
<? function cool_merge($array1,$array2){ $result=$array1; foreach($array2 as $k=>$v) if($v)$result[$k]=$v; return $result; } $foobar = Array('firstname' => 'peter','age' => '33',); $feebar = Array('firstname' => '','lastname' => 'griffin',); print_r(cool_merge($foobar,$feebar)); ?>
Если вы также хотите сохранить значения, которые пусты в обоих массивах:
array_filter($foo) + array_filter($bar) + $foo + $bar