как получить каждый столбец значений в виде массива напрямую, без использования pluck laravel? - PullRequest
0 голосов
/ 11 октября 2019

Привет, пытаясь получить значения двух столбцов в виде массивов, что-то вроде этого

"result": {
    "time": [1, 2, 4, 5, 6],
    "values": [5, 6, 7, 8, 9]
}

Я смог сделать это, используя:

$result['result'] = DB::table(TimeSignal::getTableName())->select([
    'value',
    DB::raw("(time * 0.001) as time")
])
->where('trip_id', $trip->id)
->where('signal_type_id', $timeSignalType->id)
->orderBy('time', 'asc')
->get();

затем:

$timeSignalData = $result['result'];
$result['result']['time'] = $timeSignalData->pluck('time');
$result['result']['values'] = $timeSignalData->pluck('value');

но функция pluck, которая тратит так много времени на создание объектов в виде массива, является некоторым способом сделать это быстрее, или мы можем сделать это непосредственно из запроса.

1 Ответ

1 голос
/ 12 октября 2019

Я думаю, что могу решить ваши проблемы с помощью макроса, который я нашел в Рефакторинг для коллекций .

Collection::macro('transpose', function () {
    $items = array_map(function (...$items) {
        return $items;
    }, ...$this->values());
    return new static($items);
});

Визуально это примерно так:

[1,2]                 [1,3,5]
[3,4] => transpose => [2,4,6]
[5,6]

Получить значения в коллекции

$queryCollection = DB::table(TimeSignal::getTableName())->select([
    'value',
    DB::raw("(time * 0.001) as time")
])
->where('trip_id', $trip->id)
->where('signal_type_id', $timeSignalType->id)
->orderBy('time', 'asc')
->get();

Вот как это выглядит до сих пор

# dump($queryCollection)
Illuminate\Support\Collection {
    all: [
        {
            +"value": 5,
            +"time": 1,
        },
        {
            +"value": 6,
            +"time": 2,
        },
        {
            +"value": 7,
            +"time": 4,
        },
        {
            +"value": 8,
            +"time": 5,
        },
        {
            +"value": 9,
            +"time": 6,
        },
        ...
    ],
}

Отобразить каждую строку в массив ...

$rows = $queryCollection->map(function($item) {
    return collect($item)->toArray();
}));

Теперьэто выглядит так:

# dump($rows)
Illuminate\Support\Collection {
    all: [
        [
            "value": 5,
            "time": 1,
        ],
        [
            "value": 6,
            "time": 2,
        ],
        [
            "value": 7,
            "time": 4,
        ],
        [
            "value": 8,
            "time": 5,
        ],
        [
            "value": 9,
            "time": 6,
        ],
        ...
    ],
}

Теперь мы транспонируем это.

$rows = $rows->transpose()

Что дает нам

# dump($rows)

Illuminate\Support\Collection {
    all: [
        [
            5,
            6,
            7,
            8,
            9
        ],
        [
            1,
            2,
            4,
            5,
            6,
        ],
    ]
}

И, наконец, мы добавляем ключи:

$result = collect(['values', 'time'])->combine($rows)

Что дает нам, наконец:

# dump($result)
Illuminate\Support\Collection {
    all: [
        "values" => [
            5,
            6,
            7,
            8,
            9
        ],
        "time" => [
            1,
            2,
            4,
            5,
            6,
        ],
    ]
}
# dump($result['time'])
[
    1,
    2,
    4,
    5,
    6,
]
# dump($result['values'])
[
    5,
    6,
    7,
    8,
    9,
]

Меньше шагов:

$queryCollection = DB::table(TimeSignal::getTableName())->select([
    'value',
    DB::raw("(time * 0.001) as time")
])
->where('trip_id', $trip->id)
->where('signal_type_id', $timeSignalType->id)
->orderBy('time', 'asc')
->get();

$result = collect(['values', 'time'])->combine($queryCollection->map(function ($item) {
    return collect($item)->toArray();
})->transpose());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...