Вопрос

I would like to subtract the quantity of $array2 from the stocks of $array1.

$array1= ([product_id]=>4, [stocks]=>20)

$array2= ([product_id]=>4, [quantity]=>3)

So that would be:
$array1= ([0]=> 4, [1] => 20);
$array2= ([0]=> 4, [1] => 3);

And then the output should be:

$array1= ([0]=> 4, [1] => 17);
Это было полезно?

Решение

Your array structure looks slightly different with multiple records, the code works out like this in an ugly manner. I'm assuming you're talking about something like this:

$array1 = array(
    0=>array('product_id'=>4, 'stocks'=>20), 
    1=>array('product_id'=>5, 'stocks'=>60));
$array2 = array(
    0=>array('product_id'=>4, 'quantity'=>3)
    1=>array('product_id'=>5, 'quantity'=>30));

...It's a multi-dimensional array (typical for records pulled from a database).

foreach($array1 as $key=>$value){
    foreach($array2 as $key2=>$value2) {
        if($value['product_id']==$value2['product_id']){
            $value['stocks'] -= $value2['quantity'];
            //optimization to avoid searching this again.
            unset($array2[$key]);
        }
    }}

Другие советы

With what you have given the following will do what you are asking for:

if($array1['product_id'] == $array2['product_id']) {
    $array1['stocks'] -= $array2['quantity'];
}

If you need to loop through a bigger array then what I have given is only part of the larger puzzle.

Jesse's answer wasn't tested and will not provide the desired output because the "stocks" array wasn't being modified -- a copy of the array was being modified in the loop -- so if you try to print the result to screen, there would be no change.

To modify by reference, use & just before the value variable in the first loop.

Also the unset() key must come from the inner loop to be accurate.

Additionally, if the "sales" "product_id"s are unique, then breaking the inner loop upon matching will improve performance. (This is how array_search() works.)

Code: (Demo)

$stocks = [
    ['product_id'=>2, 'stocks'=>50], 
    ['product_id'=>3, 'stocks'=>100],
    ['product_id'=>4, 'stocks'=>20], 
    ['product_id'=>5, 'stocks'=>60]
];
$sales = [
    ['product_id'=>4, 'quantity'=>3],
    ['product_id'=>5, 'quantity'=>30]
];

foreach ($stocks as &$row) {                             // modify by reference
    foreach ($sales as $k => $row2) {                    // search for product_id match
        if ($row['product_id'] == $row2['product_id']) {
            $row['stocks'] -= $row2['quantity'];         // subtract
            unset($sales[$k]);                           // eliminate match from lookup array
            break;                                       // assuming $sales['product_id'] values are unique
        }
    }
}

var_export($stocks);

Output:

array (
  0 => 
  array (
    'product_id' => 2,
    'stocks' => 50,
  ),
  1 => 
  array (
    'product_id' => 3,
    'stocks' => 100,
  ),
  2 => 
  array (
    'product_id' => 4,
    'stocks' => 17,
  ),
  3 => 
  array (
    'product_id' => 5,
    'stocks' => 30,
  ),
)

Alternatively, you can converted the sales array into a flattened, product_id-keyed array to serve as a lookup.

Code: (Demo)

$keyed = array_column($sales, 'quantity', 'product_id');
var_export($keyed);
echo "\n---\n";

foreach ($stocks as &$row) {                          // modify by reference
    if (isset($keyed[$row['product_id']])) {          // search for product_id match
        $row['stocks'] -= $keyed[$row['product_id']]; // subtract
    }
}

var_export($stocks);

Output:

array (
  4 => 3,
  5 => 30,
)
---
array (
  0 => 
  array (
    'product_id' => 2,
    'stocks' => 50,
  ),
  1 => 
  array (
    'product_id' => 3,
    'stocks' => 100,
  ),
  2 => 
  array (
    'product_id' => 4,
    'stocks' => 17,
  ),
  3 => 
  array (
    'product_id' => 5,
    'stocks' => 30,
  ),
)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top