5

カタログ用のパッケージ エンジンを設計しています。ここでは、パッケージと割引に特定の量の製品を追加できます。製品を注文すると、スクリプトはどのパッケージ取引が注文に適用されるかを検出する必要があります。

これが私のコードです:

// 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_diffarray_intersectが、それらはすべて重複した値ではうまく機能しません。

誰かがこれを解決するためのより良い/有効な方法を持っていますか?
(PSは、ソースが異なるため、連想配列を操作できません)

4

2 に答える 2

0

私は問題を分割します。その一部は、リスト内でパッケージを見つけることです。まさにそれを行う既存の関数はconsecutive_values、おそらく関連する質問で名前が付けられています:配列内の連続した値を検索しています

これにより、配列を別の配列内に正確な順序で配置することができます。これはおそらくあなたが望むものです。

残りの部分は、パッケージを検索することであり、非常に簡単です。質問を正しく理解した場合は、残り物も返す必要があります。

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);
}
于 2012-10-17T10:10:35.743 に答える
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);
于 2012-10-17T12:05:29.643 に答える