2017-08-16 140 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

正如你可以看到几乎所有我们做的是使用内置的功能,用简单的非嵌套循环自举它来满足我们的需要。这实际上是高级编程语言编程的目标。因为您自己编写的代码越少,引入系统的错误就越少。