Compare array with duplicate values ​​with array_intersect?

I am designing a batch engine for my catalog. Here you can add a certain number of products to the package and discount. When you order products, the script should determine which packages are relevant to your order.

Here is my code:

// 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); 

Result:

 Array ( [0] => package1 [1] => package1 ) Array ( [5] => 2 ) 

But I want the result to be:

 Array ( [0] => package1 [1] => package2 ) Array ( [5] => 2 ) 

I tried array_diff , array_intersect , but they all do not work with duplicate values.

Does anyone have a better / working way to resolve this issue?
(PS because of different sources I can not work with associative arrays)

+4
source share
2 answers

I would solve the problem. Part of it is to find the package inside the list. An existing function that does exactly what consecutive_values was called in a possibly related question: Search for consecutive values ​​in an array .

With this, you can find the array in another array in the exact order. This is probably what you want.

The rest is the search for packages then quite straightforward. If you correctly understood your question, you also want to go back and forth:

 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 /questions/1440256/searching-for-consecutive-values-in-an-array/4449460#4449460 $has = consecutive_values($package, $list); if ($has === -1) continue; $found[] = $name; array_splice($list, $has, count($package)); } return array($found, $list); } 

Output:

 array(2) { [0] => string(8) "package1" [1] => string(8) "package2" } array(1) { [0] => int(2) } 

Edit: A slight modification is required several times to search for the same package. This creates an internal while loop that needs to be broken if the current package is not found:

 function find_packages(array $packages, array $list) { $found = array(); foreach($packages as $name => $package) { while (true) { # consecutive_values() is @link /questions/1440256/searching-for-consecutive-values-in-an-array/4449460#4449460 $has = consecutive_values($package, $list); if ($has === -1) break; $found[] = $name; array_splice($list, $has, count($package)); } } return array($found, $list); } 
0
source
 // 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); 
0
source

Source: https://habr.com/ru/post/1440254/


All Articles