在PHP中对复杂数组进行多重排序

时间:2012-12-03 16:57:49

标签: php arrays sorting

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

问题:我们的订单中的产品需要根据以下条件过滤到“shipto”组:产品发货日期,产品是否可以与其他产品分组产品,以及产品可以从哪个仓库运输。如果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是产品首次发货的日期(即2012年12月1日的20121201; Ymd,00000000代表今天所以它们可以按数字排序)和$ group是一个布尔说法,如果产品能够或不能与其他项目一起发货(即1表示是,0表示否)< / p>

我最初的想法是基于组,然后是仓库,然后是开始日期对数组进行排序。然后我将遍历数组以构建“shipto”,并且当阵列的某些组件发生变化时(如Warehouse或Start),我将关闭先前的shipto并开始一个新的。如果我把集团和多个仓库从等式中拿出来,我可以使这个逻辑起作用。但我的任务要求我有他们,所以我遇到了以下并发症。

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

其次,由于仓库可以是逗号分隔值,我如何过滤它并获得正确的匹配。即如果我有3个产品,其仓库价值为1:1,2:3,则应分为2个出货地。一对一: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)

2 个答案:

答案 0 :(得分:1)

您是否可以将数据存储在数据库或类似的地方?听起来你的数据非常复杂,将它存储在数据库中会使你想要的排序变得更加容易。

答案 1 :(得分:0)

最后这个问题变得更加复杂,我通常抛弃了能够逻辑排序并将子排序应用于单个数组或SQL查询的概念。业务逻辑变化如此之大,以至于保持这一切并不是一蹴而就的。

最后的逻辑应用了4级过滤,所以我所做的就是隔离逻辑的每一步,并将前一个数组过滤到一个新的数组中,并将命令放在适当的位置。它不是处理此问题的最有效方法,但它非常易读,并且允许我清楚地了解每个订单在流程的每个步骤中如何排序。 “排序”阵列深度为4级,但允许我挑选每批货物以便正确显示。