1

我在 PHP 中有一个相对复杂的数组,需要以特定方式排序,但过滤器和排序的数量有点复杂,一个简单的解决方案似乎让我无法理解。

问题:我们的订单中的产品需要根据以下标准过滤到“发货”组中:产品可以发货的日期,产品是否可以与其他产品分组,以及在哪个仓库中产品可以发货。如果 2 个产品具有相同的日期、仓库和允许分组,则它们将一起放置在同一个“shipto”中。

当前解决方案(未完全实现)

当我提取订单时,我会遍历其中的项目并使用以下信息构建一个数组(仅供参考,这可能包含比我解决此问题所需的更多信息)

$allProducts = array();
$today = date("Ymd");

/* If the product is being shipped now, put in the Today ShipTo dated 00000000 */
if (($today > $start) && ($today < $end)) {
    array_push($allProducts, array('ship' => '00000000', 'defaultwarehouse' => $defaultwarehouse, 'warehouse' => $warehouse, 'group' => $group,'product' => $product, 'start_month' => $start_month, 'start_day' => $start_day, 'end_month' => $end_month, 'end_day' => $end_day, 'description' => $description, 'qty_ordered' => $qty_ordered, 'row_total' => $row_total, 'price' => $price, 'tax_amount' => $tax_amount, 'shipping_group' => $shippingGroup, 'today' => $today, 'end' => $end, 'start' => $start ) );
} else {
    /* If the product is not being shipped today, put in a Group that matches the starts date for the ShipTo */
    array_push($allProducts, array('ship' => $start, 'defaultwarehouse' => $defaultwarehouse, 'warehouse' => $warehouse, 'group' => $group, 'product' => $product, 'start_month' => $start_month, 'start_day' => $start_day, 'end_month' => $end_month, 'end_day' => $end_day, 'description' => $description, 'qty_ordered' => $qty_ordered, 'row_total' => $row_total, 'price' => $price, 'tax_amount' => $tax_amount, 'shipping_group' => $shippingGroup, 'today' => $today, 'end' => $end, 'start' => $start  ));
}
endif;

其中 $defaultwarehouse 是代表默认仓库的数字(即 1),$warehouse 是产品可以在的所有可能的仓库(即 1,2),$start 是产品可以首次发货的日期(即 20121201 2012 年 12 月 1 日;Ymd, 00000000 代表今天,因此可以对它们进行数字排序),$group 是一个布尔值,表示产品是否可以与其他物品一起发货(即 1 表示是,0 表示否)

我最初的想法是根据组对数组进行排序,然后是仓库,然后是开始日期。然后我会遍历数组来构建“shipto”,当数组的某些组件发生变化(如仓库或开始)时,我会关闭前一个 shipto 并开始一个新的。如果我将 Group 和 Multiple Warehouses 排除在外,我可以让这个逻辑发挥作用。但是我的任务需要我把它们放进去,所以我遇到了以下并发症。

首先,在按 Group 排序后,我真的想对其余的过滤器进行 Group=Yes 和 Group=No 的 2 个子排序。这让我想到,也许我应该将数组分成 2 个数组,并以类似但分开的方式对它们进行排序。这样做似乎效率低下,但我不确定。

其次,由于仓库可以是逗号分隔值,我如何过滤它并获得正确的匹配。即,如果我有 3 种产品,它们的仓库价值为 1:1,2:3,这应该分为 2 个shiptos。一个用于 1:1,2,另一个用于 3。

对问题的思考

我的感觉是我正在考虑将项目过滤到可遍历数组中的问题的方式可能不是解决它的最佳方法。可能我需要将订单项目单独推送到一个新的“发货”数组中,该数组检查每个项目与所有当前的“发货”。但我也不确定这将如何工作。或者可能有一种不同的方式我根本没有考虑如何实现这一点。

示例数组数据(为简单起见删除了额外数据):

[0]=> 
 'ship' => 00000000
 'defaultwarehouse' => 1
 'warehouse' => 1
 'group' => 1
 'sku' => 'ABC123'
[1]=>
 'ship' => 00000000
 'defaultwarehouse' => 1
 'warehouse' => 1,2
 'group' => 1
 'sku' => 'DEF234'
[2]=>
 'ship' => 00000000
 'defaultwarehouse' => 2
 'warehouse' => 1,2
 'group' => 1
 'sku' => 'GHI567'
[3]=>
 'ship' => 20121220
 'defaultwarehouse' => 1
 'warehouse' => 1,2
 'group' => 1
 'sku' => 'JKL890'
[4]=>
 'ship' => 20121220
 'defaultwarehouse' => 1
 'warehouse' => 1,2
 'group' => 1
 'sku' => 'MNO123'
[5]=>
 'ship' => 20130401
 'defaultwarehouse' => 1
 'warehouse' => 1
 'group' => 1
 'sku' => 'PQR456'
[6]=>
 'ship' => 20130401
 'defaultwarehouse' => 1
 'warehouse' => 1
 'group' => 0
 'sku' => 'STU789'

这应该会产生 5 个“shipto”组:

shipto[1] => ABC123, DEF234 (Base "group" for all other comparisons)
shipto[2] => GHI567 (Default warehouse does not match, previous shiptos)
shipto[3] => JKL890, MNO123 (Different shipping date)
shipto[4] => PRQ456 (Different shipping date from all others)
shipto[5] => STU789 (Can not be grouped with other shipments)
4

2 回答 2

1

您是否可以将数据存储在数据库或类似的地方?听起来您的数据非常复杂,将其存储在数据库中将使您希望进行的排序变得更加容易。

于 2012-12-03T17:58:08.977 回答
0

最后,这个问题变得更加复杂,我通常抛弃了能够进行逻辑排序并将子排序应用于单个数组或 SQL 查询的概念。业务逻辑发生了如此大的变化,以至于在一个维度上保持一切正常毫无意义。

最终的逻辑应用了 4 级过滤,所以我所做的就是隔离逻辑的每一步,并将前一个数组过滤成一个新数组,其中的订单位于适当的位置。这不是处理这个问题的最有效方法,但它非常易读,让我可以清楚地看到每个订单在流程的每个步骤中是如何排序的。“排序”数组有 4 层深,但允许我挑选每批货物以进行正确显示。

于 2013-01-18T14:45:45.820 回答