#laravel #loops #filter
#laravel #циклы #Фильтр
Вопрос:
$products = $category - > products;
foreach($params as $key => $item) {
if ($key === 'attribute') {
$attributes = $item;
// dd($attributes);
foreach($attributes as $subkey => $value) {
// dd($subkey, $value);
$attr_ids = ProductAttribute::where('name', $subkey) - > pluck('id') - > toArray();
// print_r($attr_ids);
// dd($attr_ids);
foreach($attr_ids as $attr_id) {
$filtered_products = new Collection();
$filtered_products = $products - > filter(function($item) use($attr_id, $value)
{
// echo $attr_id;
$item - > characteristics - > each(function($charac) use($value)
{
// print_r($charac->value);
// dd($value);
return in_array($charac - > value, $value);
});
});
$products = $filtered_products;
}
}
}
}
Я разрабатываю фильтр.
после извлечения товаров по категориям
Я перебираю URL параметров (который есть http://127.0.0.1:8000/dariy?attribute[size][0]=xsamp;attribute[rang][0]=blackamp;property[color][0]=greenamp;property[color][1]=tomato
)
в БД у меня есть таблица products, productCharacteristics и productAttributes.
Я извлекаю идентификаторы атрибутов по имени, которые указаны в параметрах (ключ).
productCharacteristics извлекается по взаимосвязи.
пока я просматриваю характеристики продукта, я сравниваю значение каждой характеристики со значением из параметров.
если правильно, я должен вернуть true для filter. но вот где я застрял. внутри закрытия фильтра есть каждый, поэтому я не могу вернуться непосредственно к filter. Как я могу это сделать?
I’m
Ответ №1:
foreach ($params as $key => $item) {
if ($key === 'attribute' amp;amp; !empty($item)) {
$filtered_products = new Collection();
$attributes = $item;
// dd($attributes);
foreach ($attributes as $subkey => $value) {
// dd($subkey, $value);
$attr_ids = ProductAttribute::where('name', $subkey)->pluck('id')->toArray();
// print_r($attr_ids);
// dd($attr_ids);
$attr_status = false; // assume there's no match
foreach ($attr_ids as $attr_id) {
$filtered_products = $products->filter(function ($item) use ($attr_id, $value, amp;$attr_status)
{
// assume product can't pass filter
$item->status = false;
$item->characteristics->each(function ($charac) use (amp;$item, $value, $attr_id)
{
// product characteristic's attribute_id and charac value match set to tru to return to filtered prducts
if($attr_id == $charac->attribute_id amp;amp; in_array($charac->value, $value)){
$item->status = true; // now product can pass.
return true;
}
});
if ($item->status === true) {
$attr_status = true;
return true;
}else{
return false;
}
});
// setting there's a match for this filter.
if ($attr_status) {
continue 2; // skipping to next filter
}
}
}
$products = $filtered_products;
}
}
- на первом уровне каждого замыкания я устанавливаю переменную
$attr_status = false
, чтобы каждый фильтр продолжал работать.
2.in каждый атрибут продукта проверял, совпадают ли значение и идентификатор атрибута или нет
, если yes $product попадает в фильтр, и я установил$attr_status = true;
, чтобы цикл фильтрации можно было пропустить.