#php
#php
Вопрос:
У меня есть массив объектов, где каждый объект содержит массив для атрибута
$cars = [
"toyota" => ["colors" => ["red","blue"]],
"mazda" => ["colors" => ["red"]],
"honda" => ["colors" => ["blue"]],
"nissan" => ["colors" => ["red","yellow"]],
];
Мне нужна функция, которая вернет все автомобили, имеющие указанный цвет.
Я могу сделать это, используя цикл foreach.
function getCarsByColor(string $color, array $cars){
foreach($cars as $key => $car){
if(!in_array($color, $car['colors'])){
unset($cars[$key]);
}
}
return $cars;
}
Просто интересно, есть ли более прямой способ сделать это.
Спасибо.
Комментарии:
1. Вы получаете данные из mysql? Если это так, вы могли бы сделать это в своем запросе
2. Это хороший момент. На самом деле это Postgres. Объект cars хранится внутри другого объекта, как jsonb, так как бы отфильтровать это при запросе к нему?
3. что-то вроде
Select car.name, color.name from car inner join color on color.idCar = car.id where color = 'yourColorByPreparedStatementHere'
4. Я не думаю, что смогу выполнить этот запрос в jsonb. Если бы атрибуты car хранились в их столбцах, то это сработало бы
Ответ №1:
Этот подход использует array_filter()
$red_cars = array_filter($cars, function($car) {
return in_array('red', $car['colors']);
});
Как функция
function get_cars_by_color(array $cars, string $color = '') {
return array_filter($cars, function($car) use ($color) {
return in_array($color, $car['colors']);
});
}
use()
передает переменную из текущей области в область функций закрытия.
Ответ №2:
В том, что вы делаете, нет ничего концептуально неправильного. В этом конкретном сценарии на самом деле у вас есть только два варианта: 1) изменить копию массива, чтобы удалить ненужные записи (что вы делаете сейчас), или 2) создать новый массив с только желаемыми записями. Выбирайте сами, на самом деле. Одна вещь, которую я замечаю:
if(!in_array($color, $car['color'])){
Возможно, это опечатка, но на основе вашего определения массива не будет индекса с именем ‘color’.