Comparing array values ​​with other values ​​from the same array

What I'm trying to achieve is that it will go through an array. It will then look if the elements of the array are the same at three points: product_id, size value and color value. I want to create a new array that lists the elements, the only thing I don't want is duplicate values. I want duplicate values ​​if they are the same at those three points that the quantity will be counted together. For example, if I have 3 elements of the same product identifier of the same size and the same color, and both of the three I ordered 3 elements in my new array, it’s just 1 time, and the quantity will be 9. Therefore, in my new duplicate value I don’t there will be an array.

Current loop

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

leads to the next array

 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}] ) 

Regarding what I'm looking for ..

 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}] ) 

Solution Please note that php blade is an interface.

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

Frontend

 <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> 
+8
arrays php compare
source share
6 answers

You can achieve your goal without using nested loops. You can use the hash function product_id, size and color parameters and use this value as a new array, for example:

 $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 ]; } } 
+8
source share

Hope this helps you:

  $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; } 
+2
source share

Try this (untested, but the logic should be correct):

 $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; } } 

Change Sorry, I just re-read the message and saw that you do not want a complete solution. I'm sorry. But I hope this can show you that nested loops are a way to go with this. As mentioned in the comments, for PHP in PHP (AFAIK) there is no built-in function.

0
source share

This is not a solution, but another approach that will allow you to think about object-oriented programming.
This will help you a lot in your current and next problems.

Now you have a business example that it should be allowed in your business layer
I can help you if you want

 <?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 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; } } 

Now you can easily compare 2 Product Objects, and later updating equals() will not affect your code

0
source share

You have replies from other users.

However, I would like to publish this for Google or other users at the planning stage and for your own knowledge.

In your example, you are using a shopping cart. You should never have duplicate elements in an array in which you should use a measure of quantity in an element, and before adding to the array you check the array if the corresponding element increases the number.

as your current way of processing your code, despite the array after there is no good reason, if I were to add 20 from the same element, your current system will have an array of 20 loops, although every time I open the basket.

This other method will also provide you with support for people to add multiple quantities of items at once, and also change the quantity on your cart page

0
source share

Note the assumptions below the code

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

Assumptions:

  • 'attributes' is converted to an associative array
  • product_id, color and size values ​​are not empty in each element
-one
source share

All Articles