2012-12-13 160 views
-2

我们的软件在关联数组中提供购买的产品列表。我们需要组合这个数组并创建一个具有统一计数的新数组。然后,此阵列将用于为我们的结算部门创建采购清单。PHP组合并计数关联数组

样本数组:

Array 
(
[0] => Array 
    (
     [item] => Long Sleeve-Shirt & Hooded Sweatshirt 
     [quantity] => 1 
     [size] => Youth Small 
     [color] => Blue 
    ) 

[1] => Array 
    (
     [item] => Long Sleeve-Shirt & Hooded Sweatshirt 
     [quantity] => 1 
     [size] => Adult Small 
     [color] => Red 
    ) 

[2] => Array 
    (
     [item] => Hooded Sweatshirt Youth & Adult Sizes 
     [quantity] => 1 
     [size] => Youth Large 
     [color] => Blue 
    ) 
[3] => Array 
    (
     [item] => Long Sleeve-Shirt & Hooded Sweatshirt 
     [quantity] => 1 
     [size] => Youth Small 
     [color] => Blue 
    ) 
} 

综合阵列

Array 
(
[0] => Array 
    (
     [item] => Long Sleeve-Shirt & Hooded Sweatshirt 
     [quantity] => 2 
     [size] => Youth Small 
     [color] => Blue 
    ) 

[1] => Array 
    (
     [item] => Long Sleeve-Shirt & Hooded Sweatshirt 
     [quantity] => 1 
     [size] => Adult Small 
     [color] => Red 
    ) 

[2] => Array 
    (
     [item] => Hooded Sweatshirt Youth & Adult Sizes 
     [quantity] => 1 
     [size] => Youth Large 
     [color] => Blue 
    ) 

} 

我将如何创建一个函数来第一阵列下结合,创建第二个阵列。我能想到的唯一的事情就是创建几个foreach循环,并慢慢打破列表。我没有使用关联数组和函数,我相信做多个foreach循环会很慢,并且可以做得更有效率。

+5

这很好。你试过什么了? –

+0

有没有问题?人们怎么回答?我可以帮你解决,但我不明白你想做什么。 – Ms01

回答

1

听起来对我来说,就像你没有那么多的合并或整合数组,以至于删除重复数据一样。问题是,你有什么条件是重复的条目?每个领域都必须完全一样吗?从阅读你的问题看起来是一个肯定的答案。由于你在这里嵌套数组(而不是一个对象数组),这听起来像你需要一个好的散列算法来进行指纹识别。你可以使用PHP native cryptographic hash algorithm,但你确实不需要它们是加密安全的。我会看看murmurhash,但有other options

PHP有处理这个功能,但它不能在多维数组工作:array_unique

你也可以使用数组的PHP哈希表的实现一样来为你做到这一点。假设你只有4场,你可能不会遇到太大的问题,但你很可能已经......

但你的代码应该是这样的:

// given an array with keys for item (string), size (string) and color (string), 
// produce a unique fingerprint value identifying it 
function hashProduct(array $product) { 
    // Concatenate all the fields of the product array 
    $key = $product['item'].$product['size'].$product['color']; 

    // Add the length of the key to the end of the hash to reduce collisions 
    return ((string)murmurhash($key)) . strlen($key); 
} 

// Assume $originalArray is passed in populated with the structure you provide above 
// Build a consolidated array, selectively adding to it. 
public function consolidateProductsList(array $originalArray) { 
    $consolidatedArray = array(); 

    foreach($originalArray as $product) { 

     // fingerprint the product 
     $hash = hashProduct($product); 

     // You could also just do this: 
     // $hash = $product['item'].$product['size'].$product['color']; 
     // php treats string-type array keys as hash maps 

     if(array_key_exits($consolidatedArray[$hash]) { 
      // Still a chance of collision here, but it is very small 
      // You should try to handle it or at least report it 
      $consolidatedArray[$hash]['quantity'] += $product[quantity]; 
     } else { 
      // Product has not been encountered yet 
      $consolidatedArray[$hash] = $product; 
     } 
    } 

    return $consolidatedArray; 
} 

在碰撞散列函数就是你有两个输入产生相同的散列输出,但不相等。探测它的方式是做多头形态比较,在这种情况下:$product1['item'] === $product2['item'] && $product1['size'] === $product2[size]

我还没有运行,甚至检查在PHP错误的代码,但我希望它足以让你开始,减去固定什么错误或我犯的错别字。

+0

经过一堆修正后,就像一个魅力。感谢这个伟大的例子。 –

1

一个更通用的解决方案是定义你想小组正是领域和哪些领域应该持有的总和:

function consolidate(array $data, array $group_fields, $sum_field) 
{ 
    $res = array(); 

    foreach ($data as $item) { 
     // work out a hash based on the grouped field names 
     $hash = ''; 
     foreach ($group_fields as $field) { 
      $hash .= $item[$field]; 
     } 
     // perform summation if item hash matches 
     if (isset($res[$hash])) { 
      $res[$hash][$sum_field] += $item[$sum_field]; 
     } else { 
      $res[$hash] = $item; 
     } 
    } 

    return array_values($res); 
} 

print_r(consolidate($data, array('item', 'size', 'color'), 'quantity')); 

Demo