2010-08-30 25 views
6

我有库存的阵列(项& B)如何将数组重新分配到某个“形状”的另一个数组中。 PHP

资料A & B被出售套1 x一个& 2×B.

的项目也有各种各样的性质,这别不会影响他们如何分配到集合中。

例如:

$inventory=array(
array("A","PINK"), 
array("A","MAUVE"), 
array("A","ORANGE"), 
array("A","GREY"), 
array("B","RED"), 
array("B","BLUE"), 
array("B","YELLOW"), 
array("B","GREEN"), 
array("B","BLACK") 
); 

我要重新分配数组$库存创建$组(S),使得

$set[0] => Array 
       (
        [0] => array(A,PINK) 
        [1] => array(B,RED) 
        [2] => array(B,BLUE) 

       ) 

$set[1] => Array 
       (
        [0] => array(A,MAUVE) 
        [1] => array(B,YELLOW) 
        [2] => array(B,GREEN) 

       ) 

$set[2] => Array 
       (
        [0] => array(A,ORANGE) 
        [1] => array(B,BLACK) 
        [2] => NULL 

       ) 

$set[3] => Array 
       (
        [0] => array(A,GREY) 
        [1] => NULL 
        [2] => NULL 

       ) 

正如你所看到的。这些项目按其出现在清单中的顺序重新分配,以创建一组1 x A & 2 x B。创建该组时,颜色无关紧要。但是我需要能够找出创建$ set数组后,哪些颜色进入了哪个集合。创建集合直到所有库存用尽。如果库存项目不存在以进入集合,则插入NULL值。

在此先感谢!

回答

1

我认为所有A's来之前所有B's

$inventory=array(
       array("A","PINK"), 
       array("A","MAUVE"), 
       array("A","ORANGE"), 
       array("A","GREY"), 
       array("B","RED"), 
       array("B","BLUE"), 
       array("B","YELLOW"), 
       array("B","GREEN"), 
       array("B","BLACK") 
       ); 

for($b_start_index = 0;$b_start_index<count($inventory);$b_start_index++) { 
     if($inventory[$b_start_index][0] == 'B') { 
       break; 
     } 
} 

$set = array(); 
for($i=0,$j=$b_start_index;$i!=$b_start_index;$i++,$j+=2) { 
     isset($inventory[$j])?$temp1=$inventory[$j]:$temp1 = null; 
     isset($inventory[$j+1])?$temp2=$inventory[$j+1]:$temp2 = null; 
     $set[] = array($inventory[$i], $temp1, $temp2);                                      
} 
+0

感谢快速回复! 这当然有效。我仍然试图破译它(阵列对我来说还是新的),但从我所看到的情况来看,我认为它对我的目的不会很灵活。 这些组不总是要配置为(A,B,B)。所以我需要能够“动态地”做到这一点。 感谢您的努力 – matt 2010-08-30 05:49:55

1

为了更容易使用你的数组,你应该让这样的事情

$inv['A'] = array(
    'PINK', 
    'MAUVE', 
    'ORANGE', 
    'GREY' 
); 
$inv['B'] = array(
    'RED', 
    'BLUE', 
    'YELLOW', 
    'GREEN', 
    'BLACK' 
); 

这种方式可以循环通过他们分开。

$createdSets = $setsRecord = $bTemp = array(); 
$bMarker = 1; 
$aIndex = $bIndex = 0; 

foreach($inv['A'] as $singles){ 
    $bTemp[] = $singles; 
    $setsRecord[$singles][] = $aIndex; 
    for($i=$bIndex; $i < ($bMarker*2); ++$i) { 
     //echo $bIndex.' - '.($bMarker*2).'<br/>'; 
     if(empty($inv['B'][$i])) { 
      $bTemp[] = 'null'; 
     } else { 
      $bTemp[] = $inv['B'][$i]; 
      $setsRecord[$inv['B'][$i]][] = $aIndex; 
     } 
    } 

    $createdSets[] = $bTemp; 
    $bTemp = array(); 
    ++$bMarker; 
    ++$aIndex; 
    $bIndex = $bIndex + 2; 
} 


echo '<pre>'; 
print_r($createdSets); 
print_r($setsRecord); 
echo '</pre>'; 

要打开你的数组关联数组,这样的事情可以做

<?php 
$inventory=array(
    array("A","PINK"), 
    array("A","MAUVE"), 
    array("A","ORANGE"), 
    array("A","GREY"), 
    array("B","RED"), 
    array("B","BLUE"), 
    array("B","YELLOW"), 
    array("B","GREEN"), 
    array("B","BLACK") 
); 

$inv = array(); 
foreach($inventory as $item){ 
    $inv[$item[0]][] = $item[1]; 
} 
echo '<pre>'; 
print_r($inv); 
echo '</pre>'; 
+0

我没有想到按照您的建议构建阵列。我可以看到如何用这个工作更容易。你的解决方案可以工作,但是在分类之前就太依赖了解数组的内容。 – matt 2010-08-30 23:53:15

+1

@matt - 您应该首先定义您的存储的详细信息,否则您必须考虑过于广泛,过于普遍,更好地制定数据存储结构,否则称为业务模型,之后的所有内容都将更加高效,因为启动点是明确的。 – 2010-08-31 03:46:03

1

也许你可以使用此功能,假设:

... $inventory已经排序(所有的A都在B之前)
... $inventory是一个数字数组,盯着指数零

// $set is the collection to which the generated sets are appended 
// $inventory is your inventory, see the assumptions above 
// $aCount - the number of A elements in a set 
// $bCount - the number of B elements in a set 
function makeSets(array &$sets, array $inventory, $aCount, $bCount) { 
    // extract $aItems from $inventory and shorten $inventory by $aCount 
    $aItems = array_splice($inventory, 0, $aCount); 
    $bItems = array(); 

    // iterate over $inventory until a B item is found 
    foreach($inventory as $index => $item) { 
     if($item[0] == 'B') { 
      // extract $bItems from $inventory and shorten $inventory by $bCount 
      // break out of foreach loop after that 
      $bItems = array_splice($inventory, $index, $bCount); 
      break; 
     } 
    } 

    // append $aItems and $bItems to $sets, padd this array with null if 
    // less then $aCount + $bCount added 
    $sets[] = array_pad(array_merge($aItems, $bItems), $aCount + $bCount, null); 

    // if there are still values left in $inventory, call 'makeSets' again 
    if(count($inventory) > 0) makeSets($sets, $inventory, $aCount, $bCount); 
} 

$sets = array(); 
makeSets($sets, $inventory, 1, 2); 
print_r($sets); 

既然你提到,你没有使用数组那么多的经验,这里有链接,因为我在上面的代码中使用的函数的PHP文件:

1

此代码对库存进行排序,而无需对库存排序进行任何假设。您可以指定模式(在$ aPattern中),并遵守顺序。它也填充缺少给定默认值的条目。

<?php 

# config 
$aInventory=array(
array("A","PINK"), 
array("A","MAUVE"), 
array("A","ORANGE"), 
array("A","GREY"), 
array("B","RED"), 
array("B","BLUE"), 
array("B","YELLOW"), 
array("B","GREEN"), 
array("B","BLACK"), 
array("C","cRED"), 
array("C","cBLUE"), 
array("C","cYELLOW"), 
array("C","cGREEN"), 
array("C","cBLACK") 
); 

$aPattern = array('A','B','A','C'); 

$mDefault = null; 

# preparation 
$aCounter = array_count_values($aPattern); 

$aCurrentCounter = $aCurrentIndex = array_fill_keys(array_unique($aPattern),0); 

$aPositions = array(); 

$aFill = array(); 

foreach ($aPattern as $nPosition=>$sElement){ 

    $aPositions[$sElement] = array_keys($aPattern, $sElement); 

    $aFill[$sElement] = array_fill_keys($aPositions[$sElement], $mDefault); 

} // foreach 




$nTotalLine = count ($aPattern); 

$aResult = array(); 

# main loop 
foreach ($aInventory as $aItem){ 

    $sElement = $aItem[0]; 

    $nNeed = $aCounter[$sElement]; 

    $nHas = $aCurrentCounter[$sElement]; 

    if ($nHas == $nNeed){ 

     $aCurrentIndex[$sElement]++; 

     $aCurrentCounter[$sElement] = 1; 

    } else { 

     $aCurrentCounter[$sElement]++; 

    } // if 

    $nCurrentIndex = $aCurrentIndex[$sElement]; 

    if (!isset($aResult[$nCurrentIndex])){ 

     $aResult[$nCurrentIndex] = array(); 

    } // if 

    $nCurrentPosition = $aPositions[$sElement][$aCurrentCounter[$sElement]-1]; 

    $aResult[$nCurrentIndex][$nCurrentPosition] = $aItem; 

} // foreach 

foreach ($aResult as &$aLine){ 

    if (count($aLine)<$nTotalLine){ 

     foreach ($aPositions as $sElement=>$aElementPositions){ 

      $nCurrentElements = count(array_keys($aLine,$sElement)); 

      if ($aCounter[$sElement] != $nCurrentElements){ 

       $aLine = $aLine + $aFill[$sElement]; 

      } // if 

     } // foreach 

    } // if 

    ksort($aLine); 

    # add empty items here 

} // foreach 

# output 
var_dump($aResult); 
1

通用的解决方案,需要你指定格式的模式

$pattern = array('A','B','B'); 

输出将在

$result = array(); 

代码:

// Convert to associative array 
$inv = array(); 
foreach($inventory as $item) 
    $inv[$item[0]][] = $item[1]; 

// Position counters : int -> int 
$count = array_fill(0, count($pattern),0); 
$out = 0; // Number of counters that are "out" == "too far" 
// Progression 
while($out < count($count)) 
{ 
    $elem = array(); 
    // Select and increment corresponding counter 
    foreach($pattern as $i => $pat) 
    { 
     $elem[] = $inv[ $pat ][ $count[$i]++ ]; 
     if($count[$i] == count($inv[$pat])) 
      $out++; 
    } 
    $result[] = $elem; 
} 
相关问题