教程:Laravel 集合(Collection)的基礎用法

圖片

文章轉自: https://learnku.com/laravel/t...

更多文章: https://learnku.com/laravel/c...

Laravel 集合是 Laravel 框架中一個十分有用的工具。php

Laravel 集合就像是在 PHP 中的數組,但會更好用。

在這篇教程中,咱們將會體驗一些集合使用時的實用技巧。laravel

集合(Collection)

Illuminate\Support\Collection 類了提供一個便捷的操做數組的封裝。git

集合 Collection 類實現了部分 PHP 和 Laravel 的接口,例如:github

你能夠在這裏查看其他已實現的接口。數據庫

建立一個新的集合

一個集合可使用 collect() 幫助函數基於一個數組被建立 或者直接經過 Illuminate\Support\Collection 類實例化。數組

一個很是簡單的使用 collect() 幫助函數的示例:瀏覽器

$newCollection = collect([1, 2, 3, 4, 5]);

一個更復雜的示例:閉包

<?php

namespace app\Http\Controllers;

use Illuminate\Support\Collection;

class TestController extends Controller
{
    /**
     * Create a new collection using the collect helper method.
     */
    public function helperCollection()
    {
        $newCollection = collect([1, 2, 3, 4, 5]);
        dd($newCollection);
    }

    /**
     * Create a new collection with a Collection class instance.
     */
    public function classCollection()
    {
        $newCollection = new Collection([1, 2, 3, 4, 5]);
        dd($newCollection);
    }
}

這個幫助函數用起來要簡單不少由於你再不須要實例化 Illuminate\Support\Collection 類。app

我也有用到 dd() 幫助函數來在瀏覽器中顯示集合。看起來大概會是這樣子。框架

Sample Collection

Eloquent ORM 集合

Laravel Eloquent ORM 也以集合的形式返回數據。

Eloquent ORM 的調用會以集合的形式返回數據

爲了演示這個效果,我將初始化一個 Sqlite 數據庫。

咱們將用 Laravel 框架預置的遷移文件來建立一個用戶表,而後填充10條數據到用戶表中。

/**
     * 從用戶表獲取用戶列表
     */
    public function getUsers()
    {
        $users = User::all();
        dd($users);
    }

該控制器方法會返回一個以下顯示的全部用戶的 Laravel 集合。

List of all users as a collection

你能夠經過箭頭符號便捷的訪問集合屬性。至於實例,想要獲取 $users 集合的第一個用戶的名字,咱們能夠這樣作。

/**
     *  獲取第一個用戶的名字
     */
    public function firstUser()
    {
        $user = User::first();
        dd($user->name);
    }

建立咱們的示例集合

咱們將會使用一些最有用的集合操做技巧,你必定會以爲很好用。

在接下來的幾個章節中,我將會用到下面這套用戶表的數據以及一些自定義的集合來達到演示的目的。雖然咱們這裏是手動建立,但使用 Laravel 的模型工廠來建立也是能夠的。

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => Chasity Tillman
            [email] => qleuschke@example.org
            [age] => 51
            [created_at] => 2016-06-07 15:50:50
            [updated_at] => 2016-06-07 15:50:50
        )
    ...
)

查找數據

有多種方法能夠在集合中查找數據。

contains

contains() 方法能夠傳一個單一值,或一組鍵 / 值對或者一個回調函數,而後它會返回一個布爾值來告知目標內容是否在集合中。

/**
     * 判斷鍵 / 值對或回調內容是否存在於集合中
     *
     *
     * @return true or false
     */
    public function contains()
    {
        $users = User::all();
        $users->contains('name', 'Chasity Tillman');
        //true

        $collection = collect(['name' => 'John', 'age' => 23]);
        $collection->contains('Jane');
        //false

        $collection = collect([1, 2, 3, 4, 5]);
        $collection->contains(function ($key, $value) {
            return $value <= 5;
            //true
        });
    }

where

經過鍵值對的形式, 用 where 方法檢索集合.

where() 方法還能夠被鏈式調用。
/**
     * 使用 where 方法找到匹配的數據
     *
     * 經過鏈式調用來增長匹配條件
     */
    public function where()
    {
        $users = User::all();
        $user = $users->where('id', 2);
        // 找出 id 爲 2 的用戶

        $user = $users->where('id', 1)
                      ->where('age', '51')
                      ->where('name', 'Chasity Tillman');

        // 找出 user 集合中 id 爲 1,年齡爲 51 歲,名叫 Chasity Tillman 的用戶
    }

還有一些像 where-like 這種用於檢索的方法,我就不一一列舉的,你們能夠經過 Laravel 的官方文檔查看。

能夠着重看下面幾個:

  • whereIn() - 以鍵值對爲參數檢索集合,其中值必須是組數。
  • search() - 在一個集合中檢索值,若是有值,返回其索引,若是沒有,則返回 false 。
  • has() - 查看鍵值對是否存,返回布爾值。

過濾數據

你可能已經猜到了,用 filter() 方法過濾。

你可能也已經想到了, filter 方法會接收一個回調函數做爲參數,在回調函數中作判斷的邏輯,對嗎?你是這麼想的嗎?

/**
     * 使用 filter 方法,找出全部年齡小於 35 的用戶
     */
    public function filter()
    {
        $users = User::all();
        $youngsters = $users->filter(function ($value, $key) {
            return $value->age < 35;
        });

        $youngsters->all();
        // 全部年齡小於 35 的用戶
    }

filter 方法會接收一個回調函數做爲參數,回調函數的參數是鍵值對,具體篩選的邏輯寫在函數裏面,而且會返回全部符合條件的值。

這裏還用到了 all() 方法,它會返回一個集合裏的全部值。

排序 / 排序數據

集合容許咱們可以使用兩種簡單的方法對數據進行排序 :-

  • sortBy() - 給定數據進行升序排序
  • sortyByDesc() - 給定數據降序排序

排序方法接受一個鍵或回調函數參數用於對集合進行排序。

/**
     * 排序方法接受一個鍵或回調函數參數
     * 用於對集合進行排序。
     */
    public function sortData()
    {
        $users  = User::all();

        $youngestToOldest = $users->sortBy('age');
        $youngestToOldest->all();
        //列出以年齡升序的全部用戶

        $movies = collect([
            [
                'name' => 'Back To The Future',
                'releases' => [1985, 1989, 1990]
            ],
            [
                'name' => 'Fast and Furious',
                'releases' => [2001, 2003, 2006, 2009, 2011, 2013, 2015, 2017]
            ],
            [
                'name' => 'Speed',
                'releases' => [1994]
            ]
        ]);

        $mostReleases = $movies->sortByDesc(function ($movie, $key) {
            return count($movie['releases']);
        });

        $mostReleases->toArray();
        //列出以上映總數降序排序的電影

        dd($mostReleases->values()->toArray());
        /*
           列出以上映總數降序排序的電影並重置鍵值
        */
    }

排序方法維護每一個值的鍵。 雖然這對您的應用程序可能很重要,但您能夠經過鏈式 values() 方法將它們重置爲默認的基於零的增量值。

像往常同樣,我還使用一個將集合轉換爲數組的集合方法 toArray()

數據 分組

groupBy

對集合進行分組有助於理解您的數據。 groupBy 方法接受鍵或回調函數,並根據鍵值或返回的回調值返回分組集合。

/**
     * groupBy 返回基於鍵或回調函數分組的數據
     * 邏輯
     */
    public function grouping()
    {
        $movies = collect([
            ['name' => 'Back To the Future', 'genre' => 'scifi', 'rating' => 8],
            ['name' => 'The Matrix',  'genre' => 'fantasy', 'rating' => 9],
            ['name' => 'The Croods',  'genre' => 'animation', 'rating' => 8],
            ['name' => 'Zootopia',  'genre' => 'animation', 'rating' => 4],
            ['name' => 'The Jungle Book',  'genre' => 'fantasy', 'rating' => 5],
        ]);

        $genre = $movies->groupBy('genre');
        /*
        [
             "scifi" => [
               ["name" => "Back To the Future", "genre" => "scifi", "rating" => 8,],
             ],
             "fantasy" => [
               ["name" => "The Matrix", "genre" => "fantasy", "rating" => 9,],
               ["name" => "The Jungle Book", "genre" => "fantasy", "rating" => 5, ],
             ],
             "animation" => [
               ["name" => "The Croods", "genre" => "animation", "rating" => 8,],
               ["name" => "Zootopia", "genre" => "animation", "rating" => 4, ],
             ],
        ]
        */

        $rating = $movies->groupBy(function ($movie, $key) {
            return $movie['rating'];
        });

        /*
        [
           8 => [
             ["name" => "Back To the Future", "genre" => "scifi", "rating" => 8,],
             ["name" => "The Croods", "genre" => "animation", "rating" => 8,],
           ],
           9 => [
             ["name" => "The Matrix", "genre" => "fantasy", "rating" => 9,],
           ],
           4 => [
             ["name" => "Zootopia","genre" => "animation", "rating" => 4,],
           ],
           5 => [
             ["name" => "The Jungle Book","genre" => "fantasy","rating" => 5,],
           ],
        ]
       */
    }

獲取數據子集

給定一組數據,而後是一個集合,您可能但願獲得它的一部分。 這多是:

  • 前2條記錄
  • 最後2條記錄
  • 除2組之外的全部記錄。

集合操做幫助咱們使用少許的方法完成這些操做。

take

take 方法接受一個整數值並返回指定的項數。給定一個負數, take() 返回集合末尾的指定項數。

/**
     * take 方法返回集合中的 n 個項數。
     * 給定 -n ,返回最後 n 個項數
     */
    public function takeMe()
    {
        $list = collect([
            'Albert', 'Ben', 'Charles', 'Dan', 'Eric', 'Xavier', 'Yuri', 'Zane'
        ]);

        //獲取前兩個名字
        $firstTwo = $list->take(2);
        //['Albert', 'Ben']

        //獲取最後兩個名字
        $lastTwo = $list->take(-2);
        //['Yuri', 'Zane']
    }

chunk

chunk 方法將集合分割成大小爲 n 的較小集合。

/**
     * Chunk(n) 返回大小爲 n 的較小集合,每一個都來自原始集合
     * 
     */
    public function chunkMe()
    {
        $list = collect([
            'Albert', 'Ben', 'Charles', 'Dan', 'Eric', 'Xavier', 'Yuri', 'Zane'
        ]);

        $chunks = $list->chunk(3);
        $chunks->toArray();
        /*
        [
            ["Albert", "Ben", "Charles",],
            [3 => "Dan", 4 => "Eric", 5 => "Xavier",],
            [6 => "Yuri", 7 => "Zane",],
        ]
        */
    }

這裏有不少方法能夠達到效果。

當你傳遞數據到 blade 頁面時,你能夠將他分塊以一次得到 n 行數據,例如,將每 3 個名字裝進一行。

@foreach($list->chunk(3) as $names)
    <div class="row">
        @foreach($names as $name)
            {{ $name }}
        @endforeach
    </div>
@endforeach

你也可使用 collapse() 方法將更新的集合組轉成一個大的集合,來反轉 chunk 方法,請查看此 here.

遍歷數據

map

map 方法會遍歷集合,將每一個元素傳入一個閉包函數,該閉包函數的返回值將替換原來的元素值。

咱們建立一個由名字組成的集合,並使用 map 方法返回一個由對應名字長度組成的集合。

/**
     * map function iterates a collection through a callback
     * function and performs an operation on each value.
     */
    public function mapMe()
    {
        $names = collect([
            'Albert', 'Ben', 'Charles', 'Dan', 'Eric', 'Xavier', 'Yuri', 'Zane'
        ]);

        $lengths = $names->map(function ($name, $key) {
            return strlen($name);
        });

        $lengths->toArray();
        //[6, 3, 7, 3, 4, 6, 4, 4,]
    }

transform

雖然 map 方法建立了一個新的集合,但有時候你可能想去修改原始的集合內容。transform 提供了一個回調方法,並對同一個集合進行操做。

由於轉換不會產生新的集合,因此你無需把它賦給新的值。

/**
     * Transform 操做原始的集合。
     */
    public function transformMe()
    {
        $names = collect([
            'Albert', 'Ben', 'Charles', 'Dan', 'Eric', 'Xavier', 'Yuri', 'Zane'
        ]);

        $names->transform(function ($name, $key) {
            return strlen($name);
        });

        $names->toArray();
        //[6, 3, 7, 3, 4, 6, 4, 4,]
    }

reduce

不一樣於 map 和 transform 方法,reduce 方法返回單個值。他將每次迭代的結果傳給下一次迭代。

例如,爲了獲取一個集合中全部整數的和,reduce 會傳遞後續數字的總和,並迭代的將結果添加到下一個數字。

/**
     * 獲取一個集合中全部數字的和
     */
    public function reduceMe()
    {
        $numbers = collect([
            1, 2, 3, 4, 5, 6, 7, 8, 9, 10
        ]);

        $sum = $numbers->reduce(function ($sum, $number) {
            return $sum + $number;
        });
        //55
    }

each

each 方法經過回調函數傳遞每一個數據項。

關於 each 方法最有趣的部分是,你能夠簡單的在回調函數中返回 false 來跳出循環。

/**
     *打印小於等於五的一列數字
     *
     */
    public function eachMethod()
    {
        $numbers = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
        $smallNumbers = $numbers->each(function ($num, $key) {
            if ($num > 5) {
                return false;
            }
            echo $num .", ";
        });
        //1, 2, 3, 4, 5,
    }

every

every 方法建立一個由集合中每第 n 個元素組成的新集合。

集合論

Laravel 提供了對集合論的支持,這意味着咱們能夠對兩個不一樣集合取交集、並集等操做。

union

union 方法將給定的數組添加到集合。若是給定的數組含有與原集合同樣的鍵,則原集合的值不會被改變:

/**
     * add array values to a collection using union
     */
    public function union()
    {
        $coolPeople = collect([
            1 => 'John', 2 => 'James', 3 => 'Jack'
        ]);

        $allCoolPeople = $coolPeople->union([
            4 => 'Sarah', 1 => 'Susan', 5 =>'Seyi'
        ]);
        $allCoolPeople->all();
        /*
        [
            1 => "John", 2 => "James", 3 => "Jack", 4 => "Sarah", 5 => "Seyi",
       ]
       */
    }

intersect

intersect() 方法接收一個數組或集合做爲參數,該方法會將集合中那些不包含在傳入參數的元素移除。

/**
     * Return a list of very cool people in collection that
     * are in the given array
     */
    public function intersect()
    {
        $coolPeople = collect([
            1 => 'John', 2 => 'James', 3 => 'Jack'
        ]);

        $veryCoolPeople = $coolPeople->intersect(['Sarah', 'John', 'James']);
        $veryCoolPeople->toArray();
        //[1 => "John" 2 => "James"]
    }

能夠發現, intersect 方法的返回值保留了原有的鍵。

結論

我試圖涵蓋你可能找到你能本身找到所需的集合方法,但這仍然有太多須要學的。

最值得注意的,我留下如下內容

在 Laravel 文檔 和  Laravel API 文檔 上還有你能夠用於操做集合的更多方法,貨心你想查看一下。

要跟進本教程代碼,查看 gtihub 倉庫 here。隨意貢獻你的代碼。

文章轉自: https://learnku.com/laravel/t...

更多文章: https://learnku.com/laravel/c...
相關文章
相關標籤/搜索