我正在为我的目录设计一个包引擎。在这里,您可以在包装中添加一定数量的产品并享受折扣。当您订购产品时,脚本必须检测哪些包裹优惠适用于您的订单。
这是我的代码:
// packages
$packages["package1"] = array(1,1,2);
$packages["package2"] = array(1,2);
//orderlist
$orderlist = array(1,1,2,1,2,2);
// put the order list in a temp array
$temp_product_array = $orderlist;
foreach($packages as $pname => $package_array)
{
$no_more_package = 0;
do
{
// put the package products in a temp array
$temp_package_array = $package_array;
$is_packages_array = array_intersect($temp_package_array,$temp_product_array);
// if all package values are present
if(count($is_packages_array) == count($temp_package_array))
{
// add package name
$packages_in_order[] = $pname;
// filter the package out of the product list but keep duplicate values
foreach($temp_product_array as $key1 => $pid1)
{
foreach($temp_package_array as $key2 => $pid2)
{
if($pid1==$pid2)
{
unset($temp_product_array[$key1]);
unset($temp_package_array[$key2]);
break; // after removing go to the next product to prevent double erasing
}
}
}
}
else
{
$no_more_package = 1;
}
}
while($no_more_package<1);
}
print_r($packages_in_order);
print_r($temp_product_array);
结果是:
Array ( [0] => package1 [1] => package1 ) Array ( [5] => 2 )
但我希望结果是:
Array ( [0] => package1 [1] => package2 ) Array ( [5] => 2 )
我尝试array_diff
,array_intersect
,但它们都不能很好地处理重复值。
有没有人有更好/更有效的方法来解决这个问题? (PS因为不同的来源我无法使用关联数组)
答案 0 :(得分:0)
我会解决这个问题。部分原因是在列表中找到包。一个现有的函数,它在一个可能相关的问题中被命名为consecutive_values
:Searching for consecutive values in an array。
使用它可以按照确切的顺序在另一个数组中定位一个数组。这可能就是你想要的。
剩下的部分是搜索包然后非常简单。如果你理解你的问题,你也想要留下遗留问题:
list($found, $rest) = find_packages($packages, $orderlist);
var_dump($found, $rest);
function find_packages(array $packages, array $list)
{
$found = array();
foreach($packages as $name => $package) {
# consecutive_values() is @link https://stackoverflow.com/a/6300893/367456
$has = consecutive_values($package, $list);
if ($has === -1) continue;
$found[] = $name;
array_splice($list, $has, count($package));
}
return array($found, $list);
}
输出:
array(2) {
[0] =>
string(8) "package1"
[1] =>
string(8) "package2"
}
array(1) {
[0] =>
int(2)
}
编辑:多次搜索同一个包需要稍作修改。这里创建了一个内部while循环,如果找不到当前包,则需要中断:
function find_packages(array $packages, array $list)
{
$found = array();
foreach($packages as $name => $package) {
while (true) {
# consecutive_values() is @link https://stackoverflow.com/a/6300893/367456
$has = consecutive_values($package, $list);
if ($has === -1) break;
$found[] = $name;
array_splice($list, $has, count($package));
}
}
return array($found, $list);
}
答案 1 :(得分:0)
// packages
$packages["package1"] = array(1,1,2);
$packages["package2"] = array(1,2);
//orderlist
$orderlist = array(1,1,1,2,2,2);
// put the order list in a temp array
$temp_product_array = $orderlist;
$product_count_array = array_count_values($temp_product_array);
foreach($packages as $pname => $temp_package_array)
{
$no_more_package = 0;
do
{
$test_package_array = array();
foreach($temp_package_array as $key => $pid)
{
// check if the product is still in the order totals
if(isset($product_count_array[$pid]) && $product_count_array[$pid]>0)
{
$product_count_array[$pid]--;
$test_package_array[] = $pid;
}
else
{
$no_more_package = 1;
}
}
// check if the found products match the package count
if(count($temp_package_array)==count($test_package_array))
{
$packages_in_order[] = $pname;
}
else
{
// add the extracted products in case of incomplete package
foreach($test_package_array as $pid)
{
$product_count_array[$pid]++;
}
}
}
while($no_more_package<1);
}
print_r($packages_in_order);
print_r($product_count_array);