Skip to content

[Proposal] Eloquent Collections functional enhancements #21

Closed
@wishfoundry

Description

@wishfoundry

Propose to add the following interface to Collection class

/**
 * @method each()
 * @method filter()
 * @method slice()
 * @method sort()
 * @method hasAny()
 * @method any()
 */

This should allow for easier manipulation of collections with closures

These functions are well known and there use should be reasonably easy to guess. An example implementation might look like the following(obviously will need to be adjusted for Laravel coding standards if approved to move forward)

<?php namespace Illuminate\Database\Eloquent;

class Collection{ use FunctionalCollectionsTrait; }

trait FunctionalCollectionsTrait
{

    /**
     * Run a function over every item
     *
     * @param  Closure  $closure
     * @return bool
     */

    public function each(Closure $closure)
    {
        $this->items = array_map($closure, $this->items);
    }

    /**
     * Filter items in collection with closures
     * (keep if return true, delete if return false)
     *
     * @param  Closure  $closure
     * @return void
     */

    public function filter(Closure $closure)
    {
        $this->items =  array_filter($this->items, $closure);
    }

    /**
     * @param int $offset
     * @param int $length
     */
    public  function slice($offset, $length = 0)
    {
        if($length == 0)
            $this->items = array_slice($this->items, $offset);
        else
            $this->items = array_slice($this->items, $offset, $length);
    }


    /**
     * Sort collection by the value returned from the closure
     *
     * @param Closure $closure
     * @param string  $direction
     *
     * @return void
     */
    public function sort(Closure $closure, $direction = 'ASC')
    {
        foreach($this->items as $item)
        {
            $key = $closure($item);
            $sortable[$key] = $item;
        }
        $direction = (strtolower($direction) == 'desc') ? SORT_DESC : SORT_ASC;
        if ($direction == SORT_ASC) ksort($sortable);
        else krsort($sortable);

        $this->items = array_values($sortable);
    }

    /**
     * Check if any item matches a truth test
     *
     * @param Closure $closure
     *
     * @return bool
     */
    public function hasAny(Closure $closure)
    {
       foreach($this->items as $item)
       {
           if($closure($item)) return true;
       }
       return false;
    }

    /**
     * Determine if the collection is empty or not.
     *
     * @return bool
     */
    public function isEmpty()
    {
        return empty($this->items);
    }

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions