2009-04-27 3 views
12

Фон: Trevor работает с реализацией стандартного алгоритма PHP: возьмите основной набор пар значений по умолчанию и обновите эти пары имя-значение, но только для тех пар имя-значение, где допустимое значение обновления фактически существует.php array_merge без стирания значений?

Проблема: по-умолчанию, 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 

) 
*/ 

ОБНОВЛЕНИЕ: 2016-06-17T11: 51: 54 вопроса был обновлен с разъясняющим контекстом и переименованием переменных.

+1

Что вы хотите делать с дубликатами? – elzapp

+0

стандартное поведение для обработки дубликатов прекрасно: пара ключ-значение в платежной панели перезапишет соответствующую пару ключевых значений в foobar. Разница * * *, которую я хочу, - это никогда не позволять платежному бланку использовать значение в foobar. – dreftymac

+0

** См. Также ** (на основе python) http://stackoverflow.com/questions/38987/how-to-merge-two-python-dictionaries-in-a-single-expression/39858#39858 – dreftymac

ответ

12

Ну, если вы хотите "умный" способ сделайте это, вот оно, но это может быть не так легко читать, как просто делать цикл.

$merged = array_merge(array_filter($foo, 'strval'), array_filter($bar, 'strval')); 

редактировать: или с помощью + ...

+0

Спасибо за это. Избегание цикла можно рассматривать как своего рода «бесполезную ловкость» на каком-то уровне, возможно, но просто приятно не использовать * всегда * использовать циклы, когда что-то вроде карты, выбора или понимания списка (как реализовано в некоторых других языки) представляется более кратким. – dreftymac

+3

Использование 'trim' вместо 'strval' также очищает элементы, которые содержат только пробелы. –

1

Это приведет к дублированию в новый массив, я не знаю, если это то, что вы хотите.

<?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); 
?> 

Это будет просто гарантировать, что feebar никогда не будет пустым из значение в 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)); 
?> 
5

Попробуйте это:

$merged = array_map(
    create_function('$foo,$bar','return ($bar?$bar:$foo);'), 
    $foobar,$feebar 
); 

Не самый читаемый решение, но он должен заменить только непустые значения, независимо от того, заказать массивы передаются ..

+0

Спасибо за это. – dreftymac

4

Настройка ваших потребностей:

# 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; 
+0

Спасибо за это. – dreftymac

1

Если вы хотите сохранить значения, которые являются пустыми в обоих массивах:

array_filter($foo) + array_filter($bar) + $foo + $bar 
2
array_replace_recursive($array, $array2); 

Это решение.

+2

Хотя этот фрагмент кода может решить вопрос, [включая объяснение] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин вашего предложения кода. – JonasCz

+1

Это, безусловно, лучший ответ здесь. Благодаря! – timothymarois

+0

Согласен, это лучшее решение здесь. Никаких объяснений не требуется. Документация PHP достаточно. – GRowing

Смежные вопросы