Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Eloquent Collections functional enhancements #21

Closed
wishfoundry opened this issue Jan 13, 2013 · 9 comments
Closed

[Proposal] Eloquent Collections functional enhancements #21

wishfoundry opened this issue Jan 13, 2013 · 9 comments

Comments

@wishfoundry
Copy link

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);
    }

}
@taylorotwell
Copy link
Member

Good ideas. Will look at implementing them soon.

@jasonlewis
Copy link
Contributor

Very nice, I like it.

+1

@bencorlett
Copy link
Contributor

@taylorotwell Maybe can you make an interface in illuminate/support which has these methods? would be pretty cool to use throughout :)

@daylerees
Copy link
Contributor

A huge +1 to this, a very clean way to avoid a ton of ugly array methods and loops.

@johnnncodes
Copy link

+1 Nice nice!

@Anahkiasen
Copy link
Contributor

A lot of the methods that could be really useful for collections can be found in my Underscore package if you want ideas or if this pull is rejected.

@daylerees
Copy link
Contributor

Hi @Anahkiasen I was talking to Taylor the other evening about the possibility of this. We will see what happens :) thanks for your work on that!

@taylorotwell
Copy link
Member

Implemented each, filter, and isEmpty.

@kaning
Copy link

kaning commented Mar 27, 2013

Should the collection be mutated?

taylorotwell pushed a commit that referenced this issue Mar 1, 2019
Fix failing Redis test
dbpolito pushed a commit to dbpolito/framework that referenced this issue Oct 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants