为了账号安全,请及时绑定邮箱和手机立即绑定

相同键的两个数组值相减,并在php中得到匹配和不匹配值的结果

相同键的两个数组值相减,并在php中得到匹配和不匹配值的结果

PHP
慕少森 2021-12-03 14:46:21
我有两个数组,如 $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>";但它没有给出我想要的正确结果。
查看完整描述

3 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

正如评论中提到的,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


查看完整回答
反对 回复 2021-12-03
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

你非常接近!


$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" 函数只是为了使输出看起来与您所说的完全一样。


查看完整回答
反对 回复 2021-12-03
?
侃侃无极

TA贡献2051条经验 获得超10个赞

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


$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>";


查看完整回答
反对 回复 2021-12-03
  • 3 回答
  • 0 关注
  • 317 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信