0

I need to take sum of beds of unique date from array. I had tried with foreach but I am getting repeated data.

How can I get data like,

on 01.08.18 I have 3 bookings and sum of beds is 10

on 02.08.18 I have 3 bookings and sum of beds is 18

on 03.08.18 I have 2 bookings and sum of beds is 7

<?php
$dates = ['01.01.18', '02.01.18', '03.01.18']; //Dates are getting from daterange datepicker and preparing dates using php and stored in array. 
foreach($dates as $date) {
// fetching data from table where date is matching with "$date".
    $bookings = [
                 ['date' => '01.01.18', 'beds' => '2'],
                 ['date' => '01.01.18', 'beds' => '3'],
                 ['date' => '01.01.18', 'beds' => '5'],
                 ['date' => '02.01.18', 'beds' => '7'],
                 ['date' => '02.01.18', 'beds' => '6'],
                 ['date' => '02.01.18', 'beds' => '5'],
                 ['date' => '03.01.18', 'beds' => '2'],
                 ['date' => '03.01.18', 'beds' => '5'],
                ];

}
foreach($bookings as $booking) {
    print_r($booking['date']);
}
2
  • 3
    most easily done directly in your sql query (with SUM() and group by)! Please show how you get the data! Commented Nov 23, 2017 at 18:20
  • in php it would be a combination of array_filter() and array_reduce() Commented Nov 23, 2017 at 18:25

2 Answers 2

1

You can use array_reduce to iterate over bookings array and for each booking update the sum if dates match:

Using array_reduce

Online Demo

$result = array_reduce( $bookings, function ($carry, $booking) use ($dates) {

    $date = $booking['date'];

    // Go to the next iteration if date doesn't exist
    if ( !in_array( $date, $dates ) ) {
        return $carry;
    }

    // Update sum if we have the same date Otherwise create new array
    if ( isset( $carry[ $date ] ) ) {
        $carry[$date]['sum'] += $booking['beds'];
        $carry[$date]['count']++;
    } else {
        $carry[ $date ] = [ 'sum' => $booking['beds'], 'count' => 1 ];
    }

    return $carry;

});

Using a simple foreach

Online Demo

$result = []; 

foreach($bookings as $booking) {

    $date = $booking['date'];

    // go to the next iteration if date doesn't exists
    if ( !in_array( $date, $dates ) ) {
        continue;
    }

    if ( isset( $result[ $date ] ) ) {
        $result[$date]['sum'] += $booking['beds'];
        $result[$date]['count']++;
    } else {
        $result[ $date ] = [ 'sum' => $booking['beds'], 'count' => 1 ];
    }

}
Sign up to request clarification or add additional context in comments.

2 Comments

It seems to me that it would be better to reduce the $bookings array, to build an array with the counts and sums (e.g. see the first loop in sinaza's answer). The current approach of creating a $dates array and repeatedly filtering, plucking the beds, summing, is doing more work than is needed.
Yes, I do it now with only one loop
0

Checkout the live result here: https://3v4l.org/nHijY

$arr = array();

foreach($bookings as $booking) {
    $date = $booking['date'];

    if(array_key_exists($date, $arr))
        $arr[$date][] = $booking['beds'];
    else
        $arr[$date] = array($booking['beds']);
}

foreach($arr as $key => $value)
{
    $count = count($value);
    $sum = array_sum($value);

    echo "on {$key} I have {$count} bookings and sum of beds is {$sum}\r\n";
}

1 Comment

You could save yourself a bunch of count()s and array_sum()s by doing that work in your first foreach loop.

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.