2017-08-16 143 views
1

根據註釋進行編輯以提供說明。PHP通過關聯數組循環

我有密鑰和值的動態關聯陣列看起來像這樣:

array: ["apples" => 4 "bananas" => 4 "cherries" => 4 "dates" => 3] 

我想創建另一n大小的陣列(與動態n)的將通過串聯陣列環。

實施例:

(if n = 6): 

apples, cherries, apples 
bananas, dates, bananas 
cherries, apples, cherries 
dates, bananas 
apples, cherries 
bananas, dates 

N檔爲1和總和的所有值

代碼我到目前爲止之間是這樣的:

function makeArray($commonWords){ 
    $n = 6; 
    $result = array_fill(0,$n, ''); 
    $i = 0; 

    while (list($key, $value) = each($commonWords)) { 
    $result[$i] = $result[$i] . $key; 
    $i++; 
    } 

    return $result; 
} 

其中規定這個輸出:

array:6 [▼ 
    0 => "apples" 
    1 => "bananas" 
    2 => "cherries" 
    3 => "dates" 
    4 => "" 
    5 => "" 
] 

但第五行需要是「蘋果」,第六行需要是「香蕉」。 然後在「蘋果」需要有「櫻桃」之後的第一行,等等,就像上面的例子。

希望這提供了澄清。

+1

也許這只是我,但我不明白 – Andreas

回答

0

如果我正確理解你的問題,我想我有一個解決方案。

我將$n添加到參數列表中,而不是在函數中定義它。

function makeArray($commonWords,$n=6){ 
    $result = array_fill(0,$n,''); 
    $c = 0; 
    // while we still have words to print out 
    while(array_sum($commonWords)){ 
     foreach($commonWords as $word=>$number){ 
      // if this word is still available 
      if($number > 0){ 
       // put the separator if we have looped through at least once 
       if($c >= $n){ 
        $result[($c % $n)] .= ", "; 
       } 
       $result[($c % $n)] .= $word; 
       // reduce the number of this word available 
       $commonWords[$word]--; 
       $c++; 
      } 
     } 
    } 
    return $result; 
} 
+0

非常感謝你。你明白我需要的東西,這是一個很好的解決方案! – SuperOcean

0

這是不是很清楚你要完成什麼,但你可以做到以下幾點。

你在這裏描述

但5日線必須是「蘋果」,第六需求是 「香蕉」什麼。

圓形鏈接列表。但是由於迭代次數不能超過給定數組的總和值,所以這是一個有限的循環鏈表。你可以閱讀鏈接列表wiki

幸運的是,PHP在Standard PHP Library中有SplDoublyLinkedList類。但是,我們必須塑造它一點點地服務於我們的需求:

class CircularLinkedListWithLimit extends SplDoublyLinkedList 
{ 
    protected $limit; 

    public function __construct($limit) 
    { 
     $this->limit = $limit; 
    } 

    public function next() 
    { 
     $this->limit -= 1; 
     parent::next(); 
    } 

    public function valid() 
    { 
     return $this->limit > 0 
      ? parent::valid() || $this->rewind() || true 
      : false; 
    } 
} 

有了這個類,我們可以建立我們的名單:

$array = ["apples" => 4, "bananas" => 4, "cherries" => 4, "dates" => 3]; 

$limit = array_sum($array); 
$list = new CircularLinkedListWithLimit($limit); 

foreach ($array as $key => $_) { 
    $list->push($key); 
} 

有了這個循環列表我們可以填寫我們的表(我硬編碼$n這裏簡單起見,但你可以在功能上把這個包):

$n = 6; 

$i = 0; 
$j = 0; 
$table = array_fill($i, $n, []); 

foreach ($list as $item) { 
    $table[$i][$j] = $item; 

    $i += 1; 

    if ($i >= $n) { 
     $i = 0; 
     $j += 1; 
    } 
} 

有了這個表,你可以做你喜歡的事情。正如你所提供一定程度的預期產出,這裏是代碼,會打印:

echo implode(PHP_EOL, array_map(function ($row) { 
    return implode(', ', $row); 
}, $table)); 

這將導致

apples, cherries, apples 
bananas, dates, bananas 
cherries, apples, cherries 
dates, bananas 
apples, cherries 
bananas, dates 

這裏是working demo

正如你可以看到幾乎所有我們做的是使用內置的功能,用簡單的非嵌套循環自舉它來滿足我們的需要。這實際上是高級編程語言編程的目標。因爲您自己編寫的代碼越少,引入系統的錯誤就越少。