如何在php中减去两个相同数组的值

时间:2018-06-08 05:29:59

标签: php mysql

我有两个如下所示的数组。

Array
(
    [0] => stdClass Object
        (
            [sply_ty] => INTRB2B
            [nil_amt] => 0
            [expt_amt] => 0
            [ngsup_amt] => 0
        )

    [1] => stdClass Object
        (
            [sply_ty] => INTRB2C
            [nil_amt] => 0
            [expt_amt] => 0
            [ngsup_amt] => 0
        )

    [2] => stdClass Object
        (
            [sply_ty] => INTRAB2B
            [nil_amt] => 76.77
            [expt_amt] => 38.39
            [ngsup_amt] => 33.01
        )

    [3] => stdClass Object
        (
            [sply_ty] => INTRAB2C
            [nil_amt] => 0
            [expt_amt] => 0
            [ngsup_amt] => 0
        )

)
Array
(
    [0] => stdClass Object
        (
            [sply_ty] => INTRB2B
            [nil_amt] => 0
            [expt_amt] => 0
            [ngsup_amt] => 0
        )

    [1] => stdClass Object
        (
            [sply_ty] => INTRB2C
            [nil_amt] => 0
            [expt_amt] => 0
            [ngsup_amt] => 0
        )

    [2] => stdClass Object
        (
            [sply_ty] => INTRAB2B
            [nil_amt] => 4
            [expt_amt] => 0
            [ngsup_amt] => 1
        )

)

这里我想要一个包含相同供应类型的减去值的最终数组。

Array
(
    [0] => stdClass Object
        (
            [sply_ty] => INTRB2B
            [nil_amt] => 0
            [expt_amt] => 0
            [ngsup_amt] => 0
        )

    [1] => stdClass Object
        (
            [sply_ty] => INTRB2C
            [nil_amt] => 0
            [expt_amt] => 0
            [ngsup_amt] => 0
        )

    [2] => stdClass Object
        (
            [sply_ty] => INTRAB2B
            [nil_amt] => 72.77
            [expt_amt] => 38.39
            [ngsup_amt] => 32.01
        )

    [3] => stdClass Object
        (
            [sply_ty] => INTRAB2C
            [nil_amt] => 0
            [expt_amt] => 0
            [ngsup_amt] => 0
        )

)

如何在不使用太多foreach或使用mysql

的情况下获取此数组

2 个答案:

答案 0 :(得分:1)

最快的方法是在mysql中进行,例如:

SELECT 
a.sply_ty AS sply_ty,
(a.nil_amt - b.nil_amt) AS nil_amt,
(a.expt_amt - b.expt_amt) AS expt_amt,
(a.ngsup_amt - b.ngsup_amt) AS ngsup_amt
FROM source AS a
LEFT JOIN subtract AS b ON a.sply_ty = b.sply_ty
WHERE ...

要更快地使用foreign key加入subtract表。如果在subtract表中可能有多个匹配记录,则应在SUM表上使用GROUP BYsubtract,例如:

SELECT 
a.sply_ty AS sply_ty,
(a.nil_amt - SUM(b.nil_amt)) AS nil_amt,
(a.expt_amt - SUM(b.expt_amt)) AS expt_amt,
(a.ngsup_amt - SUM(b.ngsup_amt)) AS ngsup_amt
FROM source AS a
LEFT JOIN subtract AS b ON a.sply_ty = b.sply_ty
WHERE ...
GROUP BY a.sply_ty, a.mil_amt, a.expt_amt, a.ngsup_amt;

另一方面,如果你必须在PHP中使用array functions而不是foreach,那么它应该更快,例如:

$source = array( ... );
$subtract = array( ... );

// apply function for every element of array with using $subtract
array_walk(
    $source,
    function (&$item) use ($subtract) {
        // find matching subtract items, return array
        $subItems = array_filter(
            $subtract,
            function ($s) use ($item) {
                return $s->sply_ty == $item->sply_ty;
            },
        );
        // if its empty, just do nothing
        if (empty($subItems)) {
            return;
        }
        // if not empty get first element as only exists that I suppose, 
        // if there will be more then one element to subtract use another loop to subtract every
        $subItem = current($subItems);
        $item->nil_amt -= $subItem->nil_amt;
        $item->expt_amt -= $subItem->expt_amt;
        $item->ngsup_amt -= $subItem->ngsup_amt;
    }
);

答案 1 :(得分:0)

假设$ initial和$ substract为初始数组。

直接解决方案只是从另一个中找到密钥。

foreach($substract as $sub) {
    foreach($initial as $index => $obj) {
        if ($obj->sply_ty == $sub->sply_ty) {
            $initial[$index]->nil_amt -= $sub->nil_amt;
            $initial[$index]->expt_amt -= $sub->expt_amt;
            $initial[$index]->ngsup_amt -= $sub->ngsup_amt;
        }
    }
}

这个循环远非最佳。首先创建查找(甚至一次)

即:

$lookup = [];
foreach($initial as $index => $obj) {
    $lookup[$obj->sply_ty] = $obj;
}

foreach($substract as $sub) {
    if (isset($lookup[$sub->sply_ty])) {
        $lookup[$sub->sply_ty]->nil_amt -= $sub->nil_amt;
        $lookup[$sub->sply_ty]->expt_amt -= $sub->expt_amt;
        $lookup[$sub->sply_ty]->ngsup_amt -= $sub->ngsup_amt;
    }
}

$result = array_values($lookup);