将数组值与同一数组中的其他值进行比较

时间:2015-11-06 20:07:22

标签: php arrays compare

我想要实现的是,它将循环通过数组。然后,它将查看数组中的项是否在三个点上相同:product_id,大小值和颜色值。 我想创建一个列出项目的新数组,我唯一不想要的是重复的值。我想要重复的值,如果它们在数量将一起计数的那三个点上是相同的。就像我有3个相同产品ID同样大小和相同颜色的三个项目我在新阵列中订购了3个项目时,这只是站在一次,数量将是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>

6 个答案:

答案 0 :(得分:8)

您可以在不使用嵌套循环的情况下实现目标。您可以使用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
        ];
    }
}

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

答案 2 :(得分: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)中没有内置函数。

答案 3 :(得分: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()不会影响您的代码

答案 4 :(得分:0)

您可以从其他用户那里获得一些答案。

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

用你的例子你使用购物篮。您不应该在数组中有重复的项目,您应该在项目上使用数量度量,并且在添加到数组之前,如果匹配的项目增加了数量,则检查数组。

作为你当前的方式,你的代码正在通过数组处理后没有充分的理由,如果我要添加20个相同的项目,你的当前系统将有一个20的数组循环,但每次我打开篮子。

这种其他方法还可以让您支持人们一次添加多个项目,也可以在您的购物篮页面上编辑数量

答案 5 :(得分:-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;
}

假设:

  • &#39;属性&#39;转换为关联数组
  • product_id,Color&amp;每个元素中的大小值都是非空的