As an example I have two arrays:
Multidimensional Array 1:
$line_items = [
0 => ['price' => 41.99, 'id' => 12, 'quantity' => 1],
1 => ['price' => 155.95, 'id' => 11, 'quantity' => 1],
2 => ['price' => 21, 'id' => 13, 'quantity' => 1]
];
Regular Array 2:
$price_array = [
0 => 197.94,
1 => 21.00
];
And I want to add the prices of each array from Array 1
until they equal to the first element of Array 2
.
At that point, I want to push the arrays from Array 1
that were used to sum that price into a new array, and repeat the process.
So for example the new array would look like this from the above arrays:
$finalArray = [
[
0 => [ "price" => 41.99, "id" => 12, "quantity" => 1 ],
1 => [ "price" => 155.95, "id" => 11, "quantity" => 1 ]
],[
0 => [ "price" => 21, "id" => 13, "quantity" => 1 ]
]
];
so far I have tried this:
$disposableTransactions_array = [];
foreach($lineitems_array as $lineitems){
//add the prices to the sum
$sum += $lineitems['price'];
//should the $sum reach the value of the first element in array
if($sum == $disposableTransactions_array[0]){
//push the $lineitems into a new array
$finalPrices_array[] = $lineitems;
//reset the sum
$sum = 0;
/* remove first element from checked array to allow the next element in array to be checked */
array_shift($disposableTransactions_array);
}
}
However, I am only getting this as output, rather than both arrays that were summed together being pushed into a multidimensional array:
$finalArray = [
0 => [ "price" => 155.95, "id" => 11, "quantity" => 1 ],
1 => [ "price" => 21, "id" => 13, "quantity" => 1 ]
];
I am a bit stuck on how to get my currently ouput array, into the array I desire.
I need to do this because I need to associate the different id’s to the two different price points.
In my case the prices reflect transactions in an order, so line_items will appear in the same order as the price they are being compared against. The variable part is how many transactions are part of this order and how many line_items are present in a transaction.
2
Answers
So I believe the problem is within your foreach loop, specifically with the way you’re identifying the items that need to be put into the array (you’re only checking for the sum on the first value of your prices array at key
$disposableTransactions_array[0]
).Since your arrays weren’t attached to PHP variables*, I took some liberties in naming conventions but this code produces the output you’re looking for:
The solution I’m proposing does three things different from the code you provided:
array_search
instead of checking on$disposableTransactions_array[0]
so we can account for multiple "sums" in the$price_array
$line_items
of the items we’re adding together during the foreach loop in the form of$sum_items
. We then use$sum_items
to create our$output_array_entry
which is all of the data from$line_items
that we used to find the sum.$output_array
I will say though, this relies heavily on the way your
$line_items
array is structured. If we move any of those items to a different order, the addition may never find the correct $sum inside of $price_array and will return nothing. For Example, if our$line_items
looks like this:The first time we loop through our
$sum
is 155.95, then on the next pass our$sum
is 176.95, and then on the third pass$sum
is 218.94 – none of which are in our$price_array
. This makes me believe you may need another check – but without more context I’m not sureBecause the line items ALWAYS perfectly align with the order of the summed prices, the following approach is suitable/reliable.
Code: (Demo)
Keep pushing line items into the current element in the result array until its price total reach the defined sum in the price array. Then increment the index and reset the sum variable and proceed with pushing line items as described in the previous sentence.
As a personal challenge, I wanted to try to script a solution using reference variables. Demo
And finally, a dense, functional-style approach: Demo
As you can see, there are many, many ways to attack this task. I didn’t even mention consuming the price array while iterating …I’ll stop here.