Коллекция Laravel преобразует массив в объект

Если я запускаю $collection->filter(myFilter), Laravel делает эту раздражающую вещь, добавляя ключи к каждой модели в коллекции следующим образом:

{
    "4": {
        "myObject": "data"
    },
    "7": {
        "myObject": "data"
    }
}

Как я могу избавиться от «4» и «7», чтобы это был массив моих объектов?

Мой код, который работает:

$obj = Cars::with('brand')->orderBy('id')->get();

return $obj->filter(function($value, $key)
{
    return $value->display == true;
});

person tgun926    schedule 12.02.2017    source источник
comment
Я чувствую, что flatten() может делать то, что вам нужно, но вам нужно предоставить еще один пример кода, чтобы увидеть, как вы получаете этот вывод.   -  person Dwight    schedule 12.02.2017
comment
Да, flatten() должно помочь   -  person manniL    schedule 12.02.2017
comment
@Dwight добавил код - сглаживание сработало. Не стесняйтесь добавлять ответ, чтобы я принял его.   -  person tgun926    schedule 12.02.2017
comment
@ tgun926 Хотя flatten() в этом случае работает, values() является подходящим методом для использования. Я добавил ответ с объяснением.   -  person patricus    schedule 12.02.2017


Ответы (2)


Проблема в том, что метод filter() не изменяет ключ базового массива коллекций. Итак, Коллекция по-прежнему представляет собой массив, просто ваш массив выглядит так:

[
    4 => Object4,
    7 => Object7,
]

Хотя это вполне допустимый массив в PHP, это неправильный массив в JSON. Поскольку это не может быть представлено в виде массива в формате JSON, оно преобразуется в объект в формате JSON.

Чтобы правильно представить это в виде массива в JSON, вам просто нужно повторно ввести массив Collection. Правильным методом для этого является метод values(). Все, что он делает, это вызывает array_values для базового массива. Это превратит приведенный выше массив в это:

[
    0 => Object4,
    1 => Object7,
]

Теперь это правильный массив с числовым индексом, который JSON может понять и будет обрабатывать как массив, а не как объект.

Хотя flatten может работать в этом конкретном случае (ваша Коллекция представляет собой набор моделей Eloquent), на самом деле это неправильный метод и может привести к непредвиденным последствиям. Кроме того, он будет выполнять много дополнительной логики, которая не нужна. Лучше всего использовать правильный метод для того, чего вы пытаетесь достичь, и это метод values().

$obj = Cars::with('brand')->orderBy('id')->get();

return $obj->filter(function($value, $key)
    {
        return $value->display == true;
    })
    ->values();
person patricus    schedule 12.02.2017
comment
Ах да, @patricus прав - values - правильный метод для использования здесь, и, как уже упоминалось, он должен быть более производительным. Совсем забыл про этот метод, хорошо, что напомнили. Это должен быть принятый ответ. - person Dwight; 12.02.2017
comment
@patricus Может быть, вы можете мне помочь. Посмотрите на это: stackoverflow.com/questions/51488623/ - person Success Man; 24.07.2018

Вызов flatten() в вашей коллекции должен удалить ключи и объединить все их значения в одну коллекцию.

person Dwight    schedule 12.02.2017