Сравнение значений массива с другими значениями из того же массива

То, что я пытаюсь достичь, это то, что он будет проходить через массив. Затем будет выглядеть, если элементы массива одинаковы в трех точках: product_id, значение размера и значение цвета. Я хочу создать новый массив, в котором перечислены элементы, единственное, чего я не хочу, это дублированные значения. Я хочу, чтобы дублированные значения, если они одинаковы в тех трех точках, что количество будет подсчитываться вместе. Например, если у меня есть 3 элемента одинакового идентификатора продукта того же размера и того же цвета, и оба из трех я заказал 3 элемента в моем новом массиве, это просто 1 раз, а количество будет равно 9. Поэтому в моем новом дублирующем значении не будет массив.

Токовая петля

foreach($orders as $key => $order){ foreach($order['orderProducts'] as $key => $value){ echo '<pre>'; print_r($value['attributes']); echo '</pre>'; } } 

приводит к следующему массиву

 Array ( [id] => 2 [product_id] => 4 [order_id] => 2 [name] => swag3 [description] => haha [price] => 19.95 [proceeds] => 10.00 [quantity] => 2 [attributes] => [{"id":1,"name":"Size","value":"XS","active":1},{"id":8,"name":"Color","value":"Wit","active":1}] ) Array ( [id] => 3 [product_id] => 3 [order_id] => 3 [name] => swag2 [description] => lol [price] => 19.95 [proceeds] => 10.00 [quantity] => 2 [attributes] => [{"id":2,"name":"Size","value":"S","active":1},{"id":7,"name":"Color","value":"Zwart","active":1}] ) Array ( [id] => 4 [product_id] => 3 [order_id] => 4 [name] => swag2 [description] => lol [price] => 19.95 [proceeds] => 10.00 [quantity] => 1 [attributes] => [{"id":2,"name":"Size","value":"S","active":1},{"id":7,"name":"Color","value":"Zwart","active":1}] ) 

Что я ищу.

 Array ( [id] => 2 [product_id] => 4 [order_id] => 2 [name] => swag3 [description] => haha [price] => 19.95 [proceeds] => 10.00 [quantity] => 2 [attributes] => [{"id":1,"name":"Size","value":"XS","active":1},{"id":8,"name":"Color","value":"Wit","active":1}] ) Array ( [id] => 3 [product_id] => 3 [order_id] => 3 [name] => swag2 [description] => lol [price] => 19.95 [proceeds] => 10.00 [quantity] => 3 [attributes] => [{"id":2,"name":"Size","value":"S","active":1},{"id":7,"name":"Color","value":"Zwart","active":1}] ) 

Решение. Обратите внимание, что это блейд-php как интерфейс.

Backend

 $order // is the array with products $items = []; foreach($orders as $key => $order){ foreach($order['orderProducts'] as $op){ $i = [ 'product'=> Product::findOrFail($op->product_id)->toArray(), 'attributes' =>$op->attributes, 'quantity'=>$op->quantity ]; $matchedResult = false; $count = count($items); for($a = 0; $a < $count; $a++){ // Items with the same product_id in the $item array if($items[$a]['product']['id'] == $i['product']['id']){ //check if the attributes are also the same if($items[$a]['attributes'] === $i['attributes']){ // The attributes ar ethe same so up the quantity $items[$a]['quantity'] += $i['quantity']; $matchedResult = true; continue; // If its right there are no other matches } } } if($matchedResult === false){ // only push item if there is not a match. $items[] = $i; } } } 

Внешний интерфейс

 <div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th>Product</th> <th>quantity</th> </tr> </thead> <tbody> @foreach($items as $item) <tr> <td>{{$item['product']['name']}} @if(count($item['attributes']) > 0) <small> @foreach($item['attributes'] as $att) {{$att['name']}} - {{$att['value']}} @endforeach </small> @endif</td> <td>{{$item['quantity']}}</td> </tr> @endforeach </tbody> </table> </div> 

Вы можете достичь своей цели, не используя вложенные циклы. Вы можете использовать хеш-функцию product_id, размер и цветовые параметры и использовать это значение в качестве нового массива таких как:

 $orders = // original array; $newOrders = []; // new array foreach($orders as $order) { $pi = $order["product_id"]; // get product_id $attr = json_decode($order["attributes"]); // get attributes: $size = $attr[0]->value; // get size value $color = $attr[1]->Color; // get color $hash = sprintf("%s.%s.%s", $pi, $size, $color); // Calculate hash if ($newOrders[$hash]) { $newOrders[$hash].quantity++; // If hash is already present then just increase quantity } else { // Otherwise add new order $newOrders[$hash] = [ "order" => $order, "quantity" => 1 ]; } } 

Я надеюсь это тебе поможет:

  $sortedArray = []; foreach ($order as $array) { $tag = getTag($array); push_to_array($sortedArray,$array,$tag); } function push_to_array(&$array1,$array2,$tag) { isset($array1[$tag]) ? $array1[$tag]['quantity'] += $array2['quantity'] : $array1[$tag] = $array2; } function getTag($array) { $attribs = json_decode($array['attributes'],true); foreach ($attribs as $value) { ($value['name'] =='Size' ) && $size = $value['value']; ($value['name'] =='Color') && $color= $value['value']; } return $array['product_id'].$size.$color; } 

Попробуйте это (непроверено, но логика должна быть правильной):

 $orders = // original array; $new; // new array foreach($orders as $order) { $pi = $order["product_id"]; // get product_id $attr = json_decode($order["attributes"]); // get attributes: $size = $attr[0]->value; // get size value $color = $attr[1]->Color; // get color $duplicate = false; foreach($newOrders as $newOrder() { // loop through nested array $newPi = $newOrder["product_id"]; $newAttr = json_decode($newOrder["attributes"]); $newSize = $newAttr[0]->value; $newValue = $newAttr[1]->Color; // check to see if same if( $pi == $newPi && $size == $newSize && $color == $newColor ) { $newOrders["quantity"]++; $duplicate = true; break; } } if(!$duplicate) { $new[] = $order; } } 

Изменить : Извините, я просто перечитал ваш пост и увидел, что вы не хотите полного решения. Сожалею. Но я надеюсь, что это может показать вам, что вложенные циклы – это способ пойти с этим. Как уже упоминалось в комментариях, для PHP в PHP (AFAIK) нет встроенной функции.

Это не решение, а еще один подход, который позволит вам думать об объектно-ориентированном программировании
Это поможет вам многое в ваших текущих и следующих проблемах

Теперь у вас есть бизнес-кейс, что он должен быть разрешен в вашем бизнес-слое
Я могу помочь вам, если вы хотите

 <?php class Attribute { private $_id; private $_name; private $_value; private $_active; // TODO implement getter and setter // lTODO implement constructor } class Product { private $_id; private $_productId; // ... order_id, name, ... private $_attribute_a = array(); // it will be an array of attribute's object // TODO implement getter and setter // TODO implement constructor private function getAttributeByName($name) { // loop through attribute array object and return the right attribute // foreach ($this->_attribute_a as $attr) { // if ($attr->name === $name) return $attr; // } } public function equals($o) { if (!is_a($o, 'Product')) return FALSE; if ($this == $o) return TRUE ; if ($this->_productId === $o->_productId) { $attr1 = $this->getAttributeByName('Size'); $attr2 = $this->getAttributeByName('Size'); if ($attr1->getValue() !== $attr2->getValue()) return FALSE; $attr1 = $this->getAttributeByName('Color'); $attr2 = $this->getAttributeByName('Color'); if ($attr1->getValue() !== $attr2->getValue()) return FALSE; return TRUE; } return FALSE; } } 

Теперь вы можете легко сравнить 2 Product Object, а позже обновление equals() не повлияет на ваш код

У вас есть некоторые ответы от других пользователей.

Однако я хотел бы опубликовать это для Googlers или других пользователей на этапе планирования и для ваших собственных знаний.

В вашем примере вы используете корзину покупок. У вас никогда не должно быть повторяющихся элементов в массиве, в котором вы должны использовать меру количества на элементе, и перед добавлением в массив вы проверяете массив, если соответствующий элемент увеличивает количество.

как ваш текущий способ обработки вашего кода, несмотря на массив после того, как не было никакой веской причины, если я должен был добавить 20 из того же элемента, ваша текущая система будет иметь массив из 20 циклов, хотя каждый раз, когда я открывал корзину.

Этот другой метод также предоставит вам поддержку для людей, чтобы добавить сразу несколько количеств предметов, а также на странице вашей корзины изменить количество

Пожалуйста, обратите внимание на допущения ниже кода

 function combineDuplicates($orders) { $indexArray = array(); $uniqueArray = array(); foreach($orders as $value) { $productID = $value['product_id']; $attributes = $value['attributes']; foreach($attributes as $attribute) { switch($attribute['name']) { case 'Size' : $size = $attribute['value']; break; case 'Color': $color = $attribute['value']; break; default : break; } } if (!isset($indexArray[$productID][$size][$color])) { $indexArray[$productID][$size][$color]['count'] = 0; $uniqueArray[] = $value; } $indexArray[$productID][$size][$color]['count']++; } $orders = array(); foreach($uniqueArray as $key => $value) { $productID = $value['product_id']; $attributes = $value['attributes']; foreach($attributes as $attribute) { switch($attribute['name']) { case 'Size' : $size = $attribute['value']; break; case 'Color': $color = $attribute['value']; break; default : break; } } $uniqueArray[$key]['quantity'] = $indexArray[$productID][$size][$color]['count']; } return $uniqueArray; } 

Предположения:

  • «атрибуты» преобразуются в ассоциативный массив
  • product_id, значения Color и Size не являются пустыми в каждом элементе