【问题标题】:Compare array values with others values from the same array将数组值与同一数组中的其他值进行比较
【发布时间】:2016-02-08 01:52:27
【问题描述】:

我想要实现的是,它将在数组中循环。然后它将查看数组中的项目是否在三个点上相同:product_id、size 值和 color 值。 我想创建一个列出项目的新数组,我唯一不想要的是重复的值。我想要重复的值,如果它们在这三个点上相同,那么数量将一起计算。就像我有 3 个相同的产品 ID 相同的尺寸和相同的颜色,并且这三个我在我的新数组中订购了 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。

后端

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

【问题讨论】:

  • 没有内置函数可以做到这一点。你必须编写自己的循环来做到这一点。
  • 往正确的方向推进:嵌套循环。 foreach ($orders as $key1 =&gt; $value1) { foreach ($orders as $key2 =&gt; $value2) { test if they're the same } }
  • @AbraCadaver 这与大小和颜色属性不匹配。
  • @Barmar:是的,只是重读。
  • 您需要获取该属性 JSON 对象并将元素添加到另一个相关表中。如果你现在这样做,你会为自己省去很多麻烦。

标签: php arrays compare


【解决方案1】:

您可以在不使用嵌套循环的情况下实现目标。您可以使用 product_id、size 和 color 参数的哈希函数,并将该值用作新的数组键,如下所示:

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

【讨论】:

    【解决方案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;
            }
    

    【讨论】:

      【解决方案3】:

      试试这个(未经测试,但逻辑应该是正确的):

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

      编辑:抱歉,我刚刚重读了您的帖子,发现您不想要完整的解决方案。对不起。但我希望这可以告诉你嵌套循环是解决这个问题的方法。如 cmets 中所述,PHP (AFAIK) 中没有内置函数。

      【讨论】:

        【解决方案4】:

        这不是一个解决方案,而是另一种让你思考的方法 面向对象编程
        它将对您当前和下一个问题有很大帮助

        现在,您有一个业务案例,必须在您的业务层解决它
        如果您愿意,我可以为您提供帮助

        <?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 个 Products 对象,以后更新 equals() 不会影响您的代码

        【讨论】:

          【解决方案5】:

          您从其他用户那里得到了一些非常棒的答案。

          但是,我想为处于规划阶段的 Google 员工或其他用户发布此信息,并为您自己所知。

          在您的示例中,您使用了购物篮。您不应该在数组中有重复的项目,您应该对项目使用 Quantity 度量,并且在添加到您的数组之前,您检查数组是否存在匹配的项目会增加数量。

          作为您当前的代码处理数组的方式,如果我要添加 20 个相同的项目,那么您当前的系统将在每次打开购物篮时循环 20 个数组。

          这种其他方法还将为您提供支持人们一次添加多个数量的物品,也在您的购物篮页面上编辑数量

          【讨论】:

            【解决方案6】:

            请注意代码下方的假设

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

            假设:

            • 'attributes' 转换为关联数组
            • product_id、颜色和尺寸值在每个元素中都是非空的

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-10-23
              • 1970-01-01
              • 2016-02-17
              • 1970-01-01
              • 1970-01-01
              • 2017-10-22
              • 2019-04-03
              • 1970-01-01
              相关资源
              最近更新 更多