как вернуть true в родительский цикл фильтрации из каждого дочернего цикла в коллекции laravel

#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;

            }
}
  
  1. на первом уровне каждого замыкания я устанавливаю переменную $attr_status = false , чтобы каждый фильтр продолжал работать.
    2.in каждый атрибут продукта проверял, совпадают ли значение и идентификатор атрибута или нет
    , если yes $product попадает в фильтр, и я установил $attr_status = true;
    , чтобы цикл фильтрации можно было пропустить.