2015-11-06 19 views
8

私が達成しようとしているのは、配列をループすることです。次に、配列内の項目がproduct_id、サイズ値、およびカラー値の3つの点で同じであるかどうかを調べます。 アイテムがリストされている新しい配列を作成したいのですが、唯一必要としないのは重複した値だけです。私はそれらが3つのポイントで同じであれば、重複した値が欲しいと思います。同じ商品IDの同じ商品IDと同じ色の3つの商品と3つの商品の3つの商品が並んでいるように、これは新しい商品で3つの商品を注文したことになります。これは1回だけ表示され、数量は9となります。アレイ。配列の値を同じ配列の他の値と比較する

現在のループ私が探しているものの次の配列

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

ソートで

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] => 3 
    [attributes] => [{"id":2,"name":"Size","value":"S","active":1},{"id":7,"name":"Color","value":"Zwart","active":1}] 
) 

ソリューション が、それは、ブレードです注意してくださいフロントエンドとしてPHP。

バックエンド

$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> 
+0

これを行う組み込みの機能はありません。それを行う独自のループを作成する必要があります。 – Barmar

+0

正しい方向に押す:入れ子になったループ。 'foreach($ orders = $ key1 => $ value1){foreach($ orders2 $> 2)} { – Barmar

+0

@AbraCadaverサイズと色の属性と一致しません。 – Barmar

答えて

8

ネストループを使用せずに目的を達成できます。あなたは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 
     ]; 
    } 
} 
0

(テストされていないが、ロジックが正しいはずです)、これを試してみてください:

$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(AFAIK)ではこのための関数は組み込まれていません。

0

これはあなたがオブジェクト指向プログラミングで考えてみましょうするためのソリューションが、別のアプローチではありません
あなたが

をしたい場合、それはあなたが今、あなたの現在と次の問題

で多くのことができます、あなたはそれがあなたのビジネス層
で解決しなければならないことをビジネスケースを、持っている私はあなたを支援することができます

<?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製品のオブジェクトを比較することができ、以降、更新equals()はあなたのコードあなたが他のユーザーからのいくつかの火格子の答えを持っている

0

には影響しません。

しかし、私はこれをGoogleの計画段階や自分の知識のために投稿したいと思います。

あなたの例では、買い物カゴを使用しています。アイテムにQuantityメジャーを使用する必要がある配列内にアイテムを重複させることは決してありません。また、配列に追加する前に、一致するアイテムが存在する場合は配列をチェックしてください。

あなたの現在の方法でコードが処理されていますが、理由はありません。もしあなたが現在のシステムに20を追加すると、バスケットを開くたびに20の配列がループします。

この他の方法はまた、人々があなたのバスケットページの編集でも、一度に大量のアイテムの複数の量を追加するためにあなたがサポートします提供します

-1

コード

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

以下の前提条件に注意してください。仮定:

  • の属性は「連想配列
  • 生成物に変換されます_id、色&サイズ値は、各要素に
2

非空である私は、これはあなたを助けることを願って:

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