Hello! There is an array that comes in view:

Array ( [0] => Array ( [name] => product_1 [model] => model_1 [option] => Array ( [0] => Array ( [product_id] => 47 [name] => Размер [value] => 39 ) ) [quantity] => 10 ) [1] => Array ( [name] => product_1 [model] => model_1 [option] => Array ( [0] => Array ( [product_id] => 47 [name] => Размер [value] => 40 ) ) [quantity] => 20 ) [2] => Array ( [name] => product_2 [model] => model_2 [option] => Array ( [0] => Array ( [product_id] => 55 [name] => Размер [value] => 44 ) ) [quantity] => 30 ) ) и т.д. 

It is necessary to remove duplicates and re-record so that it looks like this:

 Array ( [0] => Array ( [name] => product_1 [model] => model_1 [option] => Array ( [0] => Array ( [product_id] => 47 [name] => Размер [value] => 39 ) [1] => Array ( [product_id] => 47 [name] => Размер [value] => 40 ) ) [quantity] => 10 ), [1] => Array ( [name] => product_2 [model] => model_2 [option] => Array ( [0] => Array ( [product_id] => 55 [name] => Размер [value] => 44 ) ) [quantity] => 30 ) 

Model can not be touched. Now I do this:

 $keys=array(); // Массив ключей, которые уже встречались foreach($products as $k=>$val) { if(array_key_exists($val['model'],$keys)) { unset($products[$k]); } else { $keys[$val['model']]=1; } } 

Now removes duplicates, but how to make it so that it adds from duplicate [option] ?

  • and you can not use an intermediate array or something? Iterate the keys and delete them in one cycle is fraught. You delete a double if you already had a key, what's the problem to take options from there first and add them to the final element? - teran
  • PS: if the model cannot be touched, then you want to write this logic into a representation? - teran
  • @teran I also thought in this direction, let's try! I am satisfied with any option that will make the result described above, I will write logic in the controller, this is not a problem. - ultimatum
  • So in the initial array, there are different “models”, that is, the final result, after all, consists not of a single element? And why quantity is taken from the first result? - teran
  • @teran Yes, there are different models, and this must be taken into account, the key quantity is not important. - ultimatum

2 answers 2

For the final result, use the new array. There is no need to store the keys that have already been encountered, it is necessary to add “products” to the resulting array with the key — the name of the model. The number of goods quantity makes sense, probably, to add to the options array, since otherwise, only the value from the first element will remain, and you most likely need to know how many "shoes" and what sizes are available.

As a result, the algorithm is as follows. If there is no key of the model-name in the resulting array, then add it, while quantity transferred to options. If there is, then add an element to options , passing along the quantity .

 $result = []; //итерируем исходные данные foreach($model as $m){ //значение имение модели для сокращения $mname = $m['model']; // переносим quantity в option $m['option'][0]['quantity'] = $m['quantity'] ; // Модель уже присутствует в результатах? if(isset($result[$mname])){ // добавляем текущий option к результирующему массиву $result[$mname]['option'][] = $m['option'][0]; } // модели в результатах нет. else { //убираем quantity, т.к. перенесли его в options unset($m['quantity']); // помещаем модель в результирующий массив $result[$mname] = $m; } } //если нужны целочисленные ключи массива $result = array_values($result); 

In the code we mean that we process some result of the join of the product tables of their "variants", and in option there is always exactly 1 element.

The result of the execution is as follows:

 [0] => Array ( [name] => product_1 [model] => model_1 [option] => Array ( [0] => Array ( [product_id] => 47 [name] => Размер [value] => 39 [quantity] => 10 ) [1] => Array ( [product_id] => 47 [name] => Размер [value] => 40 [quantity] => 20 ) ) ) [1] => Array ( [name] => product_2 [model] => model_2 [option] => Array ( [0] => Array ( [product_id] => 47 [name] => Размер [value] => 40 [quantity] => 20 ) ) ) 

( product_2 was added to the source array for clarity)

  • $ teran It looks like the truth, if you can comment on every line of code. - ultimatum
  • @ultimatum added, in passing, slightly changed the code. - teran
  • The fire. Thanks for the help. - ultimatum

Here is the working version:

 $result = []; foreach($products as $val){ $val['option'][0]['quantity'] = $val['quantity']; if(isset($result[$val['model']])) { $result[$val['model']]['option'][] = $val['option'][0]; } else { $result[$val['model']] = $val; } unset($result[$val['model']]['quantity']); } 
  • I rewrote (all ['option'] in one heap), but I need to tweak a bit: I have different models on the page in the $val['model'] array (model_1, model_2, etc.), I need to rewrite everything [' option '] for $ val [' model ']. - ultimatum
  • You can post an example of an array that should work - L. Vadim
  • Done! Corrected a question. - ultimatum
  • I fixed it, now it works with model - L. Vadim