【问题标题】:Foreach in Multi-Dimensional Array多维数组中的 Foreach
【发布时间】:2013-03-31 03:29:22
【问题描述】:

我正在尝试在 PHP 中练习/学习 foreach 循环。我了解基本的foreach。但我在多维方面挣扎。

我有一个数组来测试它:

$data = array(
        array('New York', 'New York City'),
        array('hotel', 'lodging','motel'),
        array('cheap')
    );

我想要做的是循环遍历每个可能的组合并将其分配给它自己的数组(稍后将显示为列)。

First column ('New York', 'New York City')
second column ('New York hotel', 'New York lodging', 'New York motel')
third column ('New York City hotel', 'New York City lodging', 'New York City motel')
fourth column ('New York hotel cheap', 'New York lodging cheap', 'New York motel cheap')
fifth column ('New York City hotel cheap', 'New York City lodging cheap', 'New York City motel cheap')

我将如何做到这一点?我已经尝试了几件事,但还没有接近。

更新 我的最终目标是让个人能够获取项目列表,并尝试找到所有可能的关键字。然后,这将有助于识别他们可以考虑使用的不同 SEO 关键字。 所以有时 Data 数组可能有 2 个子数组,有时它可能有 3 或 4 个。所以它需要有点动态。

第一次解决方案尝试

public function recurseful($start, $args)
{
    if (is_array($args))
        {
            foreach ($args[0] as $value)
            {
                $this->output[] = trim("{$start} {$value}");
                if (count($args) > 1)
                {
                    $this->recurseful($value, array_slice($args, 1));
                }

            }
        }
    return;
}

但是,这会将我的所有单词返回到一个数组中。这不符合我正在寻找的要求。

【问题讨论】:

  • 如果您详细说明您的输入和预期输出,我们可能更容易建立模式。
  • 我已经更新了。这是否有助于让我更清楚我想要完成什么?
  • 不太好 - 尝试用你的“SEO”字样展示一个实际的测试用例,在 $data 中使用 3 个数组,然后是所需的输出 - 否则不清楚它们之间的关系是什么。跨度>
  • 我已根据您的要求进行了更新。

标签: php arrays codeigniter multidimensional-array foreach


【解决方案1】:

您需要做的是创建一个函数,它会递归地为您执行此操作,例如......

// function for building recursive tree arrays
function recursive($array) {
    foreach($array as $key => $value) {
        if(is_array($value)) {
            // if it is an array, it will run again
            recursive($value);
        } else {
            // do something with values here
        }
    }
    // return your result set here
}

$data = array(
        array('key', 'key2'),
        array('word', 'word2','word3'),
        array(array('more','levels','than','you','need'), 'then','some','more')
    );

$result = recursive($data);

这很粗略,但根据您的工作,您只需添加流程即可得出最终的总结果。

基本上,不管你的数组有多少深度,或者数组结构的顺序,它都会继续运行。您需要做的就是确保将函数的每次扫描的结果发送(返回)回来,这取决于您对每个级别所做的操作。

不过,它应该会让你顺利进行。

【讨论】:

  • 我遵循了与您所拥有的类似的内容。但这会将所有内容返回到单个数组中,而不是多个数组中。我相信这将是一个简单的调整。根据我在第一个问题中添加的代码,您有什么建议?
【解决方案2】:

好的,这是一个非递归解决方案,我相信只要您的 $data 数组保持二维,它就会遵循所需的模式。我不会承认这实际上花了我多少次尝试......

$cols = array(array_shift($data));
while($row = array_shift($data))
  array_walk(count($cols)<=1 ? $cols : array_slice($cols, 1), 
  function($col) use($row, &$cols){
    foreach($col as $i => $prev)
      foreach($row as $j => $word)
          $tmp[count($cols)===1?$i:$j][] = "$prev $word";
    foreach($tmp as $t) $cols[] = $t;
  });

run code *PHP 5.4 +


稍微偏离主题但值得一提 - 我不知道您将这些“关键字”放在什么上下文中,但像这样发送垃圾邮件可能会构成糟糕的 SEO。

【讨论】:

  • 谢谢。但是,该数组肯定不会保持二维。我这样说是为了更简单地解释正在发生的事情。哈。但我会玩弄你所拥有的,看看我是否可以扩展一下。
  • 您对 SEO 垃圾邮件的看法是正确的。这是为了帮助生成可能的关键字列表。然后我会去 Adwords 工具看看哪些是富有成效的。通过这种方式,我可以轻松查看某个区域并识别与该区域相关的关键词,并轻松创建大量目标关键词。 (不确定这是否有意义)。
【解决方案3】:

好的。经过几个小时和大量的工作协作:这里是:

function permutate($data, $limit){
    $this->limit = $limit;
    $this->data = $data;
    $this->numLevels = count($this->data);

    $this->possiblePermutations = 1;
    foreach ($this->data as $array){
        $this->possiblePermutations *= count($array);
    }
    for ($i = 0; $i < $this->numLevels - 0; $i++){
        $this->permutations[$i] = array();
    }

    $this->recurse(0, 0, '');

    return $this->permutations;
}

private function recurse($currentLevel, $level, $string){
    if ($this->numPerms == $this->limit) 
        return;

    foreach ($this->data[$level] as $val){
        if ($this->numPerms == $this->limit) 
            return;

        $newString = "$string $val";
        if ($level == $currentLevel){
            $this->permutations[$level][] = trim($newString);
            $this->numPerms++;
        }

        if ($level < $this->numLevels - 1 AND $level <= $currentLevel){
            $this->recurse($currentLevel, $level + 1, $newString);
        }
    }

    if (! $level AND $currentLevel < $this->numLevels){
        $this->recurse($currentLevel + 1, 0, '');
    }
}

我更改了一些变量名称等。但这非常有效!

【讨论】:

  • 虽然完全可以回答并接受您自己的问题 - 此部分代码块在其当前状态下实际上对其他人没有用处,因为它显然是更大的班级。您应该改进您的答案以匹配原始问题的简化性质,以便直接复制/粘贴将展示一个工作示例。也请考虑接受关闭主题的答案。
  • 我明白你在说什么。在这种情况下,认为类部分只是一个包装器。其余代码将在我的控制器中结束。所以函数本身可以被复制/粘贴。这还不够吗?我显然对 Stack Overflow 有点新,所以我不知道一些公认的做法。所以让我知道。
猜你喜欢
  • 2012-08-14
  • 2013-11-02
  • 2015-03-01
  • 2012-05-01
  • 2017-07-02
  • 1970-01-01
  • 2013-07-23
  • 2017-10-10
相关资源
最近更新 更多