-1

I have array like as follow,

Array(
    [0] => Array(
        [account] => 251234567890,
        [price] => 83
    ) [1] => Array(
        [account] => 251234567890,
        [price] => 27
    ) [2] => Array(
        [account] => 251234564526,
        [price] => 180
    ) [3] => Array(
        [account] => 251234567890,
        [price] => 40
    )
)

now with i want to merge array with same account and sum of it's particular price.

I want output array like this,

Array(
    [251234567890] => Array(
        [account] => 251234567890,
        [price] => 150
    ) [251234564526] => Array(
        [account] => 251234564526,
        [price] => 180
    )
)

I have tried like this,

$res = array();
$k = 0;
foreach ($to_account as $vals) {
  if (array_key_exists($vals['account'], $res)) {
    $res[$k]['price'] += $vals['price'];
    $res[$k]['account'] = $vals['account'];
    $k++;
  } else {
    $res[$k] = $vals;
    $k++;
  }
}

As here in input array only two unique account is present so output array should be of that two account with sum of it's price

I have seen something like this in python from here but it want be helpful as it is in python i want it in php i hope someone can help me in this

Thank you

0

5 Answers 5

3

I would do this in two steps, first key by the account and then convert to the output format that you want:

$data = [
  [
    'account' => 251234567890,
    'price' => 83
  ],
  [
    'account' => 251234567890,
    'price' => 27
  ],
  [
    'account' => 251234564526,
    'price' => 180
  ],
  [
    'account' => 251234567890,
    'price' => 40
  ],
];


$keyed = [];
foreach ($data as $item) {
  if (!isset($keyed[$item['account']])) {
    $keyed[$item['account']] = 0;
  }
  $keyed[$item['account']] += $item['price'];
}

$merged = [];
foreach ($keyed as $account => $price) {
  $merged[] = compact('account', 'price');
}

print_r($merged);

Or, a more functional solution (which I like, but is somewhat harder to understand):

$keyed = array_reduce($data, function ($carry, $item) {
  if (!isset($carry[$item['account']])) {
    $carry[$item['account']] = 0;
  }
  $carry[$item['account']] += $item['price'];
  return $carry;
}, []);

$merged = array_map(function ($account, $price) {
  return compact('account', 'price');
}, array_keys($keyed), $keyed);
Sign up to request clarification or add additional context in comments.

Comments

2

what about if you try to do something like:

$arr = array(
    0 => array(
        'account' => 251234567890,
        'price' => 83
    ), 1 => array(
        'account' => 251234567890,
        'price' => 27
    ), 2 =>array(
        'account' => 251234564526,
        'price' => 180
    ), 3 => array(
        'account' => 251234567890,
        'price' => 40
    )
);

foreach($arr as $key => $value) {
    $newArr[$value['account']][] = $value['price'];
}

foreach($newArr as $key => $value) {
    $finalArr[] = array('account'=>$key,'price'=>array_sum($value));
}

$finalArr:

Array ( [0] => Array ( 
[account] => 251234567890 
[price] => 150 ) 
[1] => Array ( 
[account] => 251234564526 
[price] => 180 ) )

Comments

1

By assigning temporary keys, you can determine whether you are dealing with the first occurrence or not and then use the appropriate technique to either store the whole subarray or merely add value to the price element of the subarray.

Code: (Demo)

$to_account = [
  [ 'account' => 251234567890, 'price' => 83 ],
  [ 'account' => 251234567890, 'price' => 27 ],
  [ 'account' => 251234564526, 'price' => 180 ],
  [ 'account' => 251234567890, 'price' => 40 ]
];

foreach ($to_account as $row) {
    if (!isset($result[$row['account']])) {
        $result[$row['account']] = $row;
    } else {
        $result[$row['account']]['price'] += $row['price'];
        // imitate the above line if there was another column to sum
    }
}
var_export($result);

Output:

array (
  251234567890 => 
  array (
    'account' => 251234567890,
    'price' => 150,
  ),
  251234564526 => 
  array (
    'account' => 251234564526,
    'price' => 180,
  ),
)

This method does not bother to overwrite redundant account element values. To reindex the output array, merely call array_values() on it.

Comments

0

@Jeroen Noten your answer is useful for me but i have solved it my own like this,

$final_payment_array = array();

foreach ($to_account as $vals) {
     if (array_key_exists($vals['account'], $final_payment_array)) {
            $final_payment_array[$vals['account']]['price'] += $vals['price'];
            $final_payment_array[$vals['account']]['account'] = $vals['account'];
     } else {
            $final_payment_array[$vals['account']] = $vals;
       }
}

I think this one is the best solution in performance wise

Thank you

1 Comment

That is better, however does not give you the exact result that you want, as stated in your question, before you edited it. The keys of the array are now the account numbers, not 0, 1, etc. That was the reason for my approach. But if you don't care about the keys, it's fine.
0

Here is my solution. You can try this

   $myArray = array(

        0 => array(
            account => 251234567890,
            price => 83,
            ),

        1 => array(
            account => 251234567890,
            price => 27,
            ),
        2 => array(
            account => 251234564526,
            price => 180,
            ),
        3 => array(
            account => 251234567890,
            price => 40,
            ),
   );
$keyed = [];
foreach ($myArray as $item) {
  if (!isset($keyed[$item['account']])) {
    $keyed[$item['account']] = 0;
  }
  $keyed[$item['account']] += $item['price'];
}

$merged = [];
foreach ($keyed as $account => $price) {
  $merged[] = compact('account', 'price');
}

print_r($merged);

https://eval.in/506410

2 Comments

Calling two loops is unnecessary / inefficient. See my answer.
@mickmackusa ok tx.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.