根据订购的最常见产品,对“订单”进行4批排序

时间:2019-08-12 11:47:44

标签: php arrays

我有这个问题,我什至不知道如何开始。这是一个难题,可以通过多种方法解决,但我对单一解决方案一无所知。

我也有$num_of_oders % 4 == 0个订单,总会有4,8、12、16等订单。 每个订单可以有x个订购产品。

这是示例代码:

$orders = [];

$orders[0]['order_id'] = 1;
$orders[0]['products'] = [1,2,3,4,5,6,7,8,9,10];

$orders[1]['order_id'] = 2;
$orders[1]['products'] = [3,4,13,99,76,23,12,14,53];

$orders[2]['order_id'] = 3;
$orders[2]['products'] = [1,54,23,2,34,10,11,13,14,15];

$orders[3]['order_id'] = 4;
$orders[3]['products'] = [30,31,32,33,34,35];

$orders[4]['order_id'] = 5;
$orders[4]['products'] = [30,31,32,33,34,35];

$orders[5]['order_id'] = 6;
$orders[5]['products'] = [89,65,31,26,54,78,14,45,62,46,34,12];

$orders[6]['order_id'] = 7;
$orders[6]['products'] = [23,21,22,24,25,26,27,28,29];

$orders[7]['order_id'] = 8;
$orders[7]['products'] = [23,21,22,24,25,26,27,28,29];

$orders[8]['order_id'] = 9;
$orders[8]['products'] = [23,44,34,36,37,38,86,45,41,67];

$orders[9]['order_id'] = 10;
$orders[9]['products'] = [1,23,11,13,15,32,45,65,75,24];

$orders[10]['order_id'] = 11;
$orders[10]['products'] = [15,16,77,65,48,34,67,87,45,24,68,90];

$orders[11]['order_id'] = 12;
$orders[11]['products'] = [1,2,3,4,5,6,76,43,87,65,99,27,54,64,24,67,21];

$orders[12]['order_id'] = 13;
$orders[12]['products'] = [23,13,14,65,43,59,54,34,32,57,86,24,12,43,75];

$orders[13]['order_id'] = 14;
$orders[13]['products'] = [1,13,2,6,5,3,7,45,23,87,33,65,46,65,12,54,43];

$orders[14]['order_id'] = 15;
$orders[14]['products'] = [23,13,14,65,43,51,54,34,32,57,86,24,12,43,75];

$orders[15]['order_id'] = 16;
$orders[15]['products'] = [1,2,56,4,5,6,7,11,34,54,3,12,17,42,20,64,45,53,27,35,23];

foreach($orders as $order) {
    // What to do here??

}

我的问题: 我需要按4个批次过滤订单,但每个批次都需要具有/包含最常见的订购产品(产品ID)的订单。订单只能是一批。

在当前情况下,这意味着最终结果将是4个批次的数组。每批将有4个订单,这些订单将具有最常见/相同的产品ID。

这样,我将能够向用户/工作人员逐批显示订单,并且他将能够更快地从仓库中挑选产品,因为程序会自动选择/过滤大多数常用产品的订单

能帮我解决这个问题吗?

如果您需要任何其他信息,请告诉我,我会提供。谢谢!

1 个答案:

答案 0 :(得分:1)

更新

原始代码仅根据2个订单之间的常见产品进行排序,然后将最大值分组在一起。但是,这可能会产生这样的情况,您有一批4个订单,而这两对没有共同的产品。此更新的代码将查找4个批次中的最常见产品,而不是全部4个批次:

O(1)

输出:

O(n)

Demo on 3v4l.org

原始答案

这是做您想要的(我认为)的一种方法。首先,我们将每个订单与其他订单进行比较,以确定它们有多少共同的商品(使用array_intersect)。然后以相反的顺序对该列表进行排序(即,共有的产品数量从最大到最少),然后我们对其进行处理,将每个foreach ($orders as $k1 => $o1) { // find number of products in common with other orders foreach ($orders as $k2 => $o2) { if ($k2 <= $k1) continue; foreach ($orders as $k3 => $o3) { if ($k3 <= $k2) continue; foreach ($orders as $k4 => $o4) { if ($k4 <= $k3) continue; $order_set = "{$o1['order_id']}-{$o2['order_id']}-{$o3['order_id']}-{$o4['order_id']}"; $common[$order_set] = count(array_intersect($o1['products'], $o2['products'], $o3['products'], $o4['products'])); } } } } arsort($common); $orders_used = array(); foreach (array_keys($common) as $order_set) { list($o1, $o2, $o3, $o4) = explode('-', $order_set); // already output any of these orders? if (in_array($o1, $orders_used) || in_array($o2, $orders_used) || in_array($o3, $orders_used) || in_array($o4, $orders_used)) continue; $orders_used[] = $o1; $orders_used[] = $o2; $orders_used[] = $o3; $orders_used[] = $o4; // if we've used all the orders, quit if (count($orders_used) == count($orders)) break; } for ($i = 0; $i < count($orders_used); $i += 4) { $batch = array_slice($orders_used, $i, 4); echo "batch " . ($i / 4 + 1) . ": order ids " . implode(',', $batch); echo "; common products: " . $common[implode('-', $batch)] . "\n"; } 添加到batch 1: order ids 1,12,14,16; common products: 5 batch 2: order ids 3,6,13,15; common products: 3 batch 3: order ids 2,7,9,10; common products: 1 batch 4: order ids 4,5,8,11; common products: 0 数组中,就像我们在数组中找到它一样(但忽略组合)我们已经输出了其中一个订单的位置)。一旦处理完整个数组,所有订单将以order_id的相反顺序,即它们与另一个订单共有多少个产品。然后可以将该数组拆分为批次并输出:

$orders_used

输出:

$orders_used

Demo on 3v4l.org