Laravel 5 Collections: Calculating the Sum of a Collection With sum

Laravel 5 Collections: Calculating the Sum of a Collection With sum

Laravel 5

The sum is a simple method that returns the sum of all items in a collection. It also defines a $callback parameter which can be used to tell the sum method which values of the collection should be added together. If no items are in the collection, the sum method will return 0.

Signature

public function sum(
    $callback = null
);

Example Use

The following code example shows the simplest way to use the sum method:

use Illuminate\Support\Collection;

// Create a new collection instance.
$collection = new Collection([
    1, 2, 3, 4, 5
]);

// 15
$sum = $collection->sum();

After the above code has executed, the $sum variable will contain the value 15, which is indeed the sum of all the items in the collection.

The following is a more interesting example, and shows the total number of speakers at Laracon EU for the years 2013, 2014, and 2015. The number of speakers is not unique, and therefore not technically accurate:

use Illuminate\Support\Collection;

// Create a new collection instance.
$collection = new Collection([
    ['year' => '2015', 'speakers' => 12],
    ['year' => '2014', 'speakers' => 21],
    ['year' => '2013', 'speakers' => 10]

]);

// 43
$totalSpeakers = $collection->sum('speakers');

After the above code has executed, the $totalSpeakers variable would contain the value 43.

The following collection also contains the number of speakers that spoke Laracon EU from 2013 to 2015, but instead of representing the speakers as number, the collection contains lists the names of the speakers.

use Illuminate\Support\Collection;

// Create a new collection instance.
$collection = new Collection([
    [
        'year'     => '2015',
        'speakers' => [
            'Jeffrey',
            'Taylor',
            'Matt',
            'Konstantin',
            'Jessica',
            'Frank',
            'Adam',
            'Lorna',
            'Dries',
            'Ben',
            'Esther',
            'Hannes'
        ]
    ],
    [
        'year'     => '2014',
        'speakers' => [
            'Taylor',
            'Ross',
            'Erika',
            'Konstantin',
            'Andreas',
            'Kayla',
            'Matthias',
            'Mathias',
            'Ben',
            'Rafael',
            'Igor',
            'Michelle',
            'Adam',
            'Xander',
            'Wim',
            'Mitchell',
            'Gabriela',
            'Matt',
            'Frank',
            'Hannes',
            'Kirk'
        ]
    ],
    [
        'year'     => '2013',
        'speakers' => [
            'Taylor',
            'Fabien',
            'Phill',
            'Jordi',
            'Kapil',
            'Matthew',
            'Frank',
            'Jeffrey',
            'Ben',
            'Ross'
        ]
    ]
]);

The total number of speakers can be counted using the sum method by passing a function as the argument to the $callback parameter. The callback function passed must define one parameter, which will be the value of the item. The following code example shows how to get the sum of all the speakers in the above collection:

// 43
$totalSpeakers = $collection->sum(function($value) {
    return count($value['speakers']);
});

After the above code has executed, the value of $totalSpeakers will be 43, just as it was in the previous example. It is important to note that the callback function should return a numerical value, and in the above example it is returning the result of the count function.

Using sum With Higher Order Messages

Higher order messages are a concept that allows you to invoke methods on objects within a collection using property accessors syntax. The following example will use the Laracon EU collection be built in the previous section. We will create a new Conference class to represent our conferences:

The Conference Class:

class Conference
{

    /**
     * The conference speakers.
     *
     * @var array
     */
    protected $speakers = [];

    /**
     * The name of the conference.
     *
     * @var string
     */
    protected $name = '';

    /**
     * Instantiates a new Conference instance.
     *
     * @param string $name The name of the conference.
     */
    public function __construct($name)
    {
        $this->name = $name;
    }

    /**
     * Sets the conference speakers and
     * returns the Conference instance.
     *
     * @param  array $speakers
     * @return $this
     */
    public function withSpeakers($speakers) {
        $this->speakers = $speakers;

        return $this;
    }

    /**
     * Returns the number of speakers.
     *
     * @return int
     */
    public function numberOfSpeakers()
    {
        return count($this->speakers);
    }
}

Using our new Conference class, we can utilize the transform method to convert our conference arrays into Conference object instances:

$conferences = $collection->transform(function ($item) ) {
   return with(new Conference($item['year']))
              ->withSpeakers($item['speakers']);
});

The $conferences collection will now contain Conference object instances instead of our previous arrays. Our particular implementation of Conference exposes a method numberOfSpeakers which simply returns the number of speakers at that particular conference instance.

Using Laravel's collection higher order messages, we can invoke this method to produce a sum of all conference speakers:

Calculating a Sum with Higher Order Messages:

// Determine the number of speakers at all conferences
// using higher order messages.
$totalSpeakers = $conferences->sum->numberOfSpeakers();

Like before, after the above code has executed, the $totalSpeakers variable would contain the value 43.

Start the Discussion

Leave a comment

Subscribe to our newsletter