-2

我们的软件以关联数组的形式提供购买的产品列表。我们需要组合这个数组并创建一个具有合并计数的新数组。然后,该数组将用于为我们的计费部门创建采购清单。

样本数组:

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 循环会很慢,而且可以做得更有效率。

4

2 回答 2

1

在我看来,您与其说是合并或合并数组,不如说是删除重复项。问题变成了,条目重复的条件是什么?每个字段都必须完全相同吗?从阅读您的问题来看,它看起来是肯定的。由于您在这里嵌套了数组(而不是对象数组),因此在我看来您需要一个好的哈希算法来进行指纹识别。您可以使用PHP 本机加密哈希算法,但您真的不需要它们是加密安全的。我会看看murmurhash,但还有其他选择

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 错误,但希望它足以让你开始,减去修复我所做的任何错误或拼写错误。

于 2012-12-13T20:58:35.983 回答
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'));

演示

于 2012-12-14T01:41:17.567 回答