过滤PHP数组,以便只保留唯一记录

时间:2015-03-04 13:12:41

标签: php arrays

我有这个PHP数组:

array (size=9753)
  0 => 
    array (size=3)
      'brand' => string 'Brand #1' (length=8)
      'name' => string 'Customer #13' (length=12)
      'total' => string '93.00' (length=5)
  1 => 
    array (size=3)
      'brand' => string 'Brand #1' (length=8)
      'name' => string 'Customer #23' (length=12)
      'total' => string '77.00' (length=5)
  2 => 
    array (size=3)
      'brand' => string 'Brand #1' (length=8)
      'name' => string 'Customer #32' (length=12)
      'total' => string '98.00' (length=5)
  ...

我想对其进行过滤,以便只为每个独特品牌保留total值最高的记录(共有100个品牌)。此样本的操作结果应为:

  0 => 
    array (size=3)
      'brand' => string 'Brand #1' (length=8)
      'name' => string 'Customer #32' (length=12)
      'total' => string '98.00' (length=5)
  ...

品牌#1的total

最高

这是迭代整个数组的问题,每个品牌只留下一条记录 - 总数最高的记录。

我一直在努力,但没有成功实现这一目标。我想出的代码就是:

    $c = count($ordersData);
    for($i=1; $i<$c; $i++) {
        if($ordersData[$i]['brand'] == $ordersData[$i-1]['brand'] 
            && $ordersData[$i]['total'] > $ordersData[$i-1]['total']) {
            unset($ordersData[$i-1]);
        }
    }

,但它不会删除所有应删除的记录。

建议非常感谢。

3 个答案:

答案 0 :(得分:2)

所以看起来你最好的选择肯定是循环遍及$ ordersData中的所有记录,就像你已经完成的那样。但是,您的逻辑有点古怪,只会将ordersdata总数与之前检查的订单总数进行比较。

相反,您可能想要启动一个新数组,并根据品牌名称添加/覆盖值。这样的事情,也许是:

<?php

$results = array();

foreach($ordersData as $order) {
    $brand = $order['brand'];
    $total = $order['total'];

    // If an order of this brand has already been tracked
    if(array_key_exists($brand, $results)) {
        // and the total of the current order is greater than what we have recorded
        if($results[$brand]['total'] < $total) {
            // Then let's replace it!
            $results[$brand] = $order;
        }
    } else {
        // Never added this brand before? Add it then
        $results[$brand] = $order;
    }
}

答案 1 :(得分:0)

您可以按总计,升序对数组进行排序,然后创建一个在品牌上编制索引的临时数组(以便使用后面的(更高的)值覆盖该键),然后使用array_values获取数字索引数组:

usort($array, function($a, $b) {
    return $b['total'] - $b['total'];
});
$temp=[];
foreach($array as $element) $temp[$element['brand']]=$element;
$out = array_values($temp);

答案 2 :(得分:0)

我也提出了另一种方法。我在这里粘贴它只是为了参考(这是我最初的尝试,改进了)。

    $c = count($ordersData);
    // Let's iterate through the whole array
    for($i=0; $i<$c; $i++) {            
        // Save the current brand being checked                
        $currentBrand = $ordersData[$i]['brand'];
        // If we can still check against the next record and the this is still the same brand..
        if (key_exists($i+1, $ordersData) && $ordersData[$i]['brand'] == $ordersData[$i+1]['brand']) {
            // If the next order value for the current brand is higher..
            if ( $ordersData[$i]['total'] < $ordersData[$i+1]['total'] ) {
                //Let's save/overwrite the higher order for the current brand
                $results[$currentBrand] = $ordersData[$i+1];

            }
        }                                                                            
    }