PHP循环关联数组

时间:2017-08-16 17:45:17

标签: php arrays loops parsing

根据评论编辑提供说明。

我有一个动态关联数组,其键和值如下所示:

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 => ""
]

但第5行必须是“苹果”,第6行需要是“香蕉”。 然后在“苹果”需要“樱桃”之后的第一行,依此类推,如上例所示。

希望这可以澄清。

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

您要完成的目标并不是很清楚,但您可以执行以下操作。

你在这里描述什么

  

但第五行必须是"苹果",第六行需要   "香蕉"

循环链接列表。但由于迭代次数不能超过给定数组的和值,因此这是一个带有限制的圆形链表。您可以在wiki中了解关联列表

幸运的是,PHP在SplDoublyLinkedList中有Standard PHP Library个班级。但我们必须将其塑造一点以满足我们的需求:

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

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