2012-10-17 3 views
4

카탈로그 용 패키지 엔진을 설계하고 있습니다. 여기에서 특정 수량의 제품을 패키지에 추가하고 할인 할 수 있습니다. 제품을 주문할 때 스크립트는 주문에 적용되는 패키지 거래를 감지해야합니다.array_intersect를 사용하여 중복 된 값을 가진 배열을 비교 하시겠습니까?

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

하지만 결과가되고 싶어요 :

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

array_diff, array_intersect하지만 그들은 모두 중복 된 값으로는 잘 작동하지 않습니다.

아무에게도이 문제를 해결하는 더 나은 방법이 있습니까?
(PS는 서로 다른 소스로 인해 연관 배열과 함께 작동하지 못합니다.)

+0

그래서 orderlist이 같은 제품을 포함해야합니다 패키지로 (와 같은 순서로) ? – cmbuckley

+0

주문이 중요합니까? – hakre

+0

주문 목록에는 임의의 수의 pruduct ID가 가능한 순서로 포함되어 있습니다. (스크립트에서 패키지는 할인으로 주문됩니다.) –

답변

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) 
} 

편집 :를 약간의 수정을 필요로하는 동일한 패키지에 대해 여러 번 검색. 다음은 내부 루프는 현재 패키지가 발견되지 않은 경우 휴식이 필요 만들어집니다 동안 : 그것은 일치하는

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); 
} 
+0

이것은 완벽하게 작동합니다. 더 많은 패키지와 제품 아이디어로 테스트 해 보겠습니다. 고맙습니다!! –

+0

나는 또한 거의 같은 순간에 돌파구를 가졌습니다. 나는 나의 해결책을 게시 할 것이다. 이 문제를 해결하는 최선의 방법에 호기심. –

+0

나는 항상 문제를 함수로 나눈다. 코드는 따르기 쉽고 변경하기 쉽습니다. 또한 제대로 작동하는 잎 기능을 테스트 할 수 있습니다. – hakre

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