【问题标题】:Subtraction of two array values for same keys and and get result both matched and non-matched value in php相同键的两个数组值相减,并在php中获得匹配和不匹配值的结果
【发布时间】:2019-08-22 14:57:42
【问题描述】:

我有两个数组,如 $a 和 $b。对于相同的键,我想从 $a 减去 $b 。另外我想看到两个数组的不匹配键与减法结果。 只有匹配的键会被减去。是否可以不使用 foreach 循环?不是强制性的,它必须在没有循环的情况下解决。但是如果没有循环就更好了。示例数组在下面。

$a=Array
(

    [1] => 4.00
    [2] => 3.00
    [3] => 8.00
    [4] => 4.88
    [5] => 7.88
    [10] => 17.88
)
$b=Array
(
    [1] => 2.00
    [3] => 4.00
    [4] => 2.88
    [7] => 5.00
    [8] => 6.00    
)

我想要这样的结果

$result=array(

[1] => 2.00
[2] => 3.00
[3] => 4.00
[4] => 2.00
[5] => 7.88
[7] => 5.00
[8] => 6.00
[10] => 17.88

);

我的代码是:

$res1=$res2=$res3=array();
foreach( $a as $k1=>$v1 ){
     foreach($b as $k2=>$v2){
         if($k1==$k2){
            $res1[$k1]=$v2-$v1;
         }else{
            $res2[$k2]=v2;
            $res3[$k1]=v1;
         }
     }
}

$res[]=array_merge($res1,$res2,$res3);
echo "<pre>"; print_r($res); echo "</pre>";

但它没有给出我想要的正确结果。

【问题讨论】:

  • 不应该 7 是 -5 而 8 应该是 -6 吗?为什么这些是积极的。其余的遵循 $a - $b 的模式,但那些没有
  • 实际上积极消极对我来说并不重要。逻辑上应该是负数。
  • 是否可以不使用 foreach 循环? 为什么?
  • 我已经在我的脚本中使用了许多循环,这就是我想避免使用 foreach 的原因。顺便说一句,避免 foreach 循环不是强制性的,但如果可以避免则更好。
  • Shardj 你能帮帮我吗?

标签: php


【解决方案1】:

请尝试使用以下代码。希望它会给你想要的输出。

$res1=$res2=$res3=array();
    foreach( $a as $k1=>$v1 ){
        if(isset($b[$k1])){
            $res1[$k1]=$a[$k1]-$b[$k1];     
        }else{
            $res2[$k1]=$v1;     
        }   
    }

    $res3=array_diff_key($b, $a);
    $result = array_replace_recursive($res1,$res2,$res3);
    echo "<pre>"; print_r($result); echo "</pre>";

【讨论】:

    【解决方案2】:

    你很亲密!

    $count = count($a) + count($b);  // figure out how many times we need to loop - count total # of elements
    
    for ( $key = 1; $key <= $count ; $key++ )
    {
        if ( isset($a[$key]) && isset($b[$key]) )  $result[$key] = number_format(abs($a[$key] - $b[$key]), 2);
        elseif ( isset($a[$key]) ) $result[$key] = number_format($a[$key], 2);
        elseif ( isset($b[$key]) ) $result[$key] = number_format($b[$key], 2);
    }
    

    “number_format”和“abs”函数只是为了让输出看起来完全像你所说的那样。

    【讨论】:

      【解决方案3】:

      正如 cmets 所提到的,array_walk 本质上仍然是一个循环,因为它遍历每个元素。我已经在每个步骤中记录了代码,但基本思想是创建一个合并数组,然后更改重复项的值。有更有效的方法可以解决这个问题,但这说明了一种基本方法。

      我还应该指出,因为这是使用array_walk 和一个匿名函数(闭包),所以我们必须传入它需要的任何变量(... use (...))。如果您要使用foreach 循环(或for),则无需这样做,您可以直接访问$output$first$second

      https://3v4l.org/WD0t4#v7125

      <?php
      
      $first = [
          1 => 4.00,
          2 => 3.00,
          3 => 8.00,
          4 => 4.88,
          5 => 7.88,
          10 => 17.88
      ];
      
      $second = [
          1 => 2.00,
          3 => 4.00,
          4 => 2.88,
          7 => 5.0,
          8 => 6.00
      ];
      
      // Merge the 2 original arrays and preserve the keys
      // https://stackoverflow.com/q/17462354/296555
      // The duplicate items' value will be clobbered at this point but we don't care. We'll set them in the `array_walk` function.
      $output = $first + $second;
      
      // Create an array of the duplicates. We'll use these keys to calculate the difference.
      $both = array_intersect_key($first, $second);
      
      // Foreach element in the duplicates, calculate the difference.
      // Notice that we're passing in `&$output` by reference so that we are modifying the underlying object and not just a copy of it.
      array_walk($both, function($value, $key) use (&$output, $first, $second) {
          $output[$key] = $first[$key] - $second[$key];
      });
      
      // Finally, sort the final array by its keys.
      ksort($output);
      
      var_dump($output);
      
      // Output
      //array (size=8)
      //  1 => float 2
      //  2 => float 3
      //  3 => float 4
      //  4 => float 2
      //  5 => float 7.88
      //  7 => float 5
      //  8 => float 6
      //  10 => float 17.88
      

      以及使用foreach 循环的强制性压缩版本。

      <?php
      
      $first = [
          1 => 4.00,
          2 => 3.00,
          3 => 8.00,
          4 => 4.88,
          5 => 7.88,
          10 => 17.88
      ];
      
      $second = [
          1 => 2.00,
          3 => 4.00,
          4 => 2.88,
          7 => 5.0,
          8 => 6.00
      ];
      
      $output = $first + $second;
      foreach (array_keys(array_intersect_key($first, $second)) as $key) {
          $output[$key] = $first[$key] - $second[$key];
      }
      ksort($output);
      
      var_dump($output);
      
      // Output
      //array (size=8)
      //  1 => float 2
      //  2 => float 3
      //  3 => float 4
      //  4 => float 2
      //  5 => float 7.88
      //  7 => float 5
      //  8 => float 6
      //  10 => float 17.88
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-15
        • 2016-08-29
        • 2022-11-19
        • 1970-01-01
        相关资源
        最近更新 更多