12* полезных методов в коллекциях laravel

20 September 2018
#Linux#Collections

Коллекции в Laravel прекрасный инструмент. Кроме того, что коллекцию можно создать через функцию хелпера collect(), Eloquent так же возвращает коллекцию.

При составлении этого чарта было довольно сложно выделить наиболее любимые методы, ведь пользуюсь почти всем набором. Всё же я собрал небольшую статистику по нескольким проектам и выделил наиболее часто используемые и полезные.

  • На самом деле их тут больше =)

Для начала создадим коллекцию.

$collection = collect([
    [ 'name' => 'Laravel', 'rating' => 10, 'id' => 1],
    [ 'name' => 'CodeIgniter', 'rating' => 6, 'id' => 2],
    [ 'name' => 'Symfony', 'rating' => 4, 'id' => 3],
    [ 'name' => 'Zend Framework' , 'rating' => 4, 'id' => 4]
]);

Встречайте. Первое место чарта с небольшим отрывом от map - господин keyBy

1. keyBy()

Метод которым я ну очень часто пользуюсь. Преобразует коллекцию так, что ключом становится указанное поле

    $collection->keyBy('id');
    
    // результат
    Collection {#1830 ▼
      #items: array:4 [▼
        1 => array:3 ["name" => "Laravel"
          "rating" => 10
          "id" => 1
        ]
        2 => array:3 ["name" => "CodeIgniter"
          "rating" => 6
          "id" => 2
        ]
        3 => array:3 ["name" => "Symfony"
          "rating" => 4
          "id" => 3
        ]
        4 => array:3 ["name" => "Zend Framework"
          "rating" => 4
          "id" => 4
        ]
      ]
    }

Посмотрите что произошло, поле id стало ключом массива.

2. map() & transform()

Вторая группа методов, которыми пользуюсь не менее часто.

Все методы перебирают коллекцию. Для обработки каждого элемента используется callback функция. В тело этой callback функции передаётся один элемент коллекции.

    $result = $collection->map(function ($item, $key) {
        $item['rating'] *= 2;
        return $item;
    });
    
    // результат
    Collection {#1834 ▼
      #items: array:4 [▼
        0 => array:3 ["name" => "Laravel"
          "rating" => 20
          "id" => 1
        ]
        1 => array:3 []
        2 => array:3 []
        3 => array:3 []
      ]
    }

В данном примере, мы умножили рейтинг на 2, а результат вернули.

Метод transform() аналогичен map, с той лишь разницей, что не формирует новую коллекцию, а работает с текущей. Использую их попеременно, то map, то transform.

3. get() & has()

Эти методы я почти всегда использую в паре. has проверяет на наличие ключа, get возвращает элемент по имени ключа.

    // для начала преобразуем нашу коллекцию.
    $result = $collection->keyBy('name');
    
    if ($result->has('Other')) {
        dd($result->get('Other'));
    }
    
    if ($result->has('Laravel')) {
        dd($result->get('Laravel'));
    }
    
    // результат
    array:3 ["name" => "Laravel"
      "rating" => 10
      "id" => 1
    ]

Кстати, раз уж зашла речь о методе get, напомню, что в laravel добавить элемент в коллекцию можно методом push() (Добавит в оригинальную коллекцию)

    $collection->push([
        'name' => 'phalcon',
        'rating' => 3,
        'id' => 5
    ]);
    
    dd($collection);
    
    Collection {#232 ▼
      #items: array:5 [▼
        0 => array:3 []
        1 => array:3 []
        2 => array:3 []
        3 => array:3 []
        4 => array:3 ["name" => "phalcon"
          "rating" => 3
          "id" => 5
        ]
      ]
    }

4. sortBy() & sortByDesc()

Как видно из названия это сортировка, прямая и обратная соответственно.

    $result = $collection->sortBy('name');
    
    dd($result, $collection);
    
    // Оригинальная коллекция
    Collection {#1832 ▼
      #items: array:4 [▼
        0 => array:3 ["name" => "Laravel"
          "rating" => 10
          "id" => 1
        ]
        1 => array:3 ["name" => "CodeIgniter"
          "rating" => 6
          "id" => 2
        ]
        2 => array:3 ["name" => "Symfony"
          "rating" => 4
          "id" => 3
        ]
        3 => array:3 ["name" => "Zend Framework"
          "rating" => 4
          "id" => 4
        ]
      ]
    }
    
    //Результат сортировки
    Collection {#1834 ▼
      #items: array:4 [▼
        1 => array:3 ["name" => "CodeIgniter"
          "rating" => 6
          "id" => 2
        ]
        0 => array:3 ["name" => "Laravel"
          "rating" => 10
          "id" => 1
        ]
        2 => array:3 ["name" => "Symfony"
          "rating" => 4
          "id" => 3
        ]
        3 => array:3 ["name" => "Zend Framework"
          "rating" => 4
          "id" => 4
        ]
      ]
    }

Обратите внимание что ключи сбились (1,0,2,3), что бы их привести в нормальный порядок можно воспользоваться методом values();

    $result = $collection->sortBy('name')->values();
    dd($result);
    
    // результат
    Collection {#1835 ▼
      #items: array:4 [▼
        0 => array:3 ["name" => "CodeIgniter"
          "rating" => 6
          "id" => 2
        ]
        1 => array:3 ["name" => "Laravel"
          "rating" => 10
          "id" => 1
        ]
        2 => array:3 ["name" => "Symfony"
          "rating" => 4
          "id" => 3
        ]
        3 => array:3 ["name" => "Zend Framework"
          "rating" => 4
          "id" => 4
        ]
      ]
    }

5. groupBy()

Ещё один метод без которого я как без рук. Группирует коллекцию по указанному ключу.

    dd($collection->groupBy('rating'));
    
    // результат
    Collection {#1837 ▼
      #items: array:3 [▼
        10 => Collection {#1834 ▼
          #items: array:1 [▼
            0 => array:3 ["name" => "Laravel"
              "rating" => 10
              "id" => 1
            ]
          ]
        }
        6 => Collection {#1835 ▼
          #items: array:1 [▼
            0 => array:3 ["name" => "CodeIgniter"
              "rating" => 6
              "id" => 2
            ]
          ]
        }
        4 => Collection {#1836 ▼
          #items: array:2 [▼
            0 => array:3 ["name" => "Symfony"
              "rating" => 4
              "id" => 3
            ]
            1 => array:3 ["name" => "Zend Framework"
              "rating" => 4
              "id" => 4
            ]
          ]
        }
      ]
    }

6. where() && contains()

Метод where фильтрует коллекцию по паре ключ => значение.

    dd($collection->where('rating', 4));
    

    Collection {#656 ▼
      #items: array:2 [▼
        2 => array:3 ["name" => "Symfony"
          "rating" => 4
          "id" => 3
        ]
        3 => array:3 ["name" => "Zend Framework"
          "rating" => 4
          "id" => 4
        ]
      ]
    }

Но если вам необходимо просто проверить присутствует ли в коллекции нужная пара ключ-значение, то благоразумнее воспользоваться методом contains

        dd($collection->contains('rating', '10'));
        // вернёт true

Обратите внимание, что в качестве значения мы передаём строку, но тем не менее, метод возвратил true. Дело в том, что он использует не строгое (==) сравнение. Для строгого (===) сравнения, используйте containsStrict()

        dd($collection->containsStrict('rating', '10'));
        // тут уже вернёт false, тога как
        dd($collection->containsStrict('rating', 10));
        // вернёт true

7. filter()

Если нужно отбросить по какому-то условию часть коллекции, то filter предназначен именно для этого.

Давайте найдём только те элементы, значения ключа rating которых больше либо равен шести.

    $result = $collection->filter(function ($item) {
        return $item['rating'] >= 6;
    });
    
    dd($result);
    

    Collection {#656 ▼
      #items: array:2 [▼
        0 => array:3 ["name" => "Laravel"
          "rating" => 10
          "id" => 1
        ]
        1 => array:3 ["name" => "CodeIgniter"
          "rating" => 6
          "id" => 2
        ]
      ]
    }

8. forget()

Как видно из названия заставляет забыть элемент коллекции, в аргументы передаётся имя ключа. Данный метод изменяет переданную в него коллекцию, а не возвращает новую.

    dd($collection->keyBy('name')->forget('Zend Framework')); // Символично, да?
    
    // Результат
    Collection {#656 ▼
      #items: array:3 [▼
        "Laravel" => array:3 ["name" => "Laravel"
          "rating" => 10
          "id" => 1
        ]
        "CodeIgniter" => array:3 ["name" => "CodeIgniter"
          "rating" => 6
          "id" => 2
        ]
        "Symfony" => array:3 ["name" => "Symfony"
          "rating" => 4
          "id" => 3
        ]
      ]
    }

Обратите внимание, что здесь мы сначала воспользовались методом keyBy

9. chunk()

Устали от больших коллекций? Тогда chunk идёт к Вам.

Разобьёт коллекцию на множество мелких коллекций.

    dd($collection->chunk(2));
    
    // Результат
    Collection {#659 ▼
      #items: array:2 [▼
        0 => Collection {#666 ▼
          #items: array:2 [▼
            0 => array:3 ["name" => "Laravel"
              "rating" => 10
              "id" => 1
            ]
            1 => array:3 ["name" => "CodeIgniter"
              "rating" => 6
              "id" => 2
            ]
          ]
        }
        1 => Collection {#656 ▼
          #items: array:2 [▼
            2 => array:3 ["name" => "Symfony"
              "rating" => 4
              "id" => 3
            ]
            3 => array:3 ["name" => "Zend Framework"
              "rating" => 4
              "id" => 4
            ]
          ]
        }
      ]
    }

Аргумент указывает сколько в коллекции должно содержаться элементов, в нашем случае 2 элемента на коллекцию. Если укажем 1, то возвратит в нашем случае 4 коллекции.

10. pluck()

Вот ещё один полезный метод. Возвратит все значения ключей коллекции по указанному ключу.

    dd($plucked = $collection->pluck('name'));
    
    // Результат
    Collection {#667 ▼
      #items: array:4 [▼
        0 => "Laravel"
        1 => "CodeIgniter"
        2 => "Symfony"
        3 => "Zend Framework"
      ]
    }

11. avg() & count()

Посчитать среднее значение, ну скажем к примеру рейтинга, поможет avg()

    dd($plucked = $collection->avg('rating'));
    
    // Результат
    6
    // (10 + 6 + 4 + 4) / 4

А вот общее количество элементов коллекции подскажет count()

    dd($collection->count());
    // вернёт 4, хотя конечно можно и через обычный count
    dd(count($collection));
    // так же вернёт 4

12. implode()

И закончим чарт методом implode. Думаю что тут так же из названия понятно, что метод объединяет элементы коллекции. Передаваемые в метод аргументы зависят от типа коллекции, если мы работаем с коллекцией объектов или массивов, то нужно передавать пару ключ-значение

    dd($collection->implode('name', ', '));
    
    // Результат
    "Laravel, CodeIgniter, Symfony, Zend Framework"

Если коллекция сожержит строковые либо числовые значения, то потребуется только аргумент "объединения"

    dd($collection->pluck('name')->implode('-'));
    "Laravel-CodeIgniter-Symfony-Zend Framework"

Послесловие

Чтобы преобразовать коллекцию в массив нужно просто вызвать метод toArray()

    $collection->toArray();

На этом всё.

Делитесь статьёй в соцсетях, сохраняйте в закладки и пользуйтесь ;)

Если вы хотети предложить статью, или стать автором на нашем сайте, пишите на public@softroot.ru