【问题标题】:php array_merge without erasing values?php array_merge 不删除值?
【发布时间】:2010-10-22 01:31:14
【问题描述】:

背景: 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

)
*/

更新: 2016-06-17T11:51:54 更新了问题,澄清了上下文并重命名了变量。

【问题讨论】:

标签: php arrays merge


【解决方案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));
?>

【讨论】:

    【解决方案2】:

    好吧,如果你想要一种“聪明”的方式来做到这一点,就在这里,但它可能不像简单地循环那样可读。

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

    编辑:或使用 +...

    【讨论】:

    • 谢谢你。避免循环在某种程度上可能被视为一种“无用的聪明才智”——但在 map、select 或列表理解(以其他一些语言实现)看起来更简洁。
    • 使用 'trim' 而不是 'strval' 也会清除仅包含空格的项目。
    【解决方案3】:

    试试这个:

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

    不是最易读的解决方案,但它应该只替换非空值,无论数组传递的顺序如何..

    【讨论】:

      【解决方案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;
      

      【讨论】:

        【解决方案5】:

        如果您还想保留两个数组中的空白值:

        array_filter($foo) + array_filter($bar) + $foo + $bar
        

        【讨论】:

          【解决方案6】:
          array_replace_recursive($array, $array2);
          

          这就是解决方案。

          【讨论】:

          • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
          • 这是迄今为止最好的答案。谢谢!
          • 我同意,这是最好的解决方案。无需解释。 PHP 文档就足够了。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多