数组排列组合问题:我需要的是如何得到数组的所有排列组合。

3
你们中的任何人都可能做过我下面提到的这种组合。
$data = array
(
    'a1' => array(7, 32,44),
    'a2' => array(4,44),
    'a3' => array(9,33,55)
);

如果我尝试检索n次,那么返回的结果应该类似于这样。假设n=4(从0到3)。
Array
(
    [0] => Array
        (
            [0] => 7  // from a1
            [1] => 4  // from a2
            [2] => 9  // from a3         
        )

    [1] => Array
        (
            [0] => 32
            [1] => 44
            [2] => 33           
        )

    [2] => Array
        (
            [0] => 44
            [1] => 4
            [2] => 55           
        )


    [3] => Array
        (
            [0] => 7
            [1] => 44
            [2] => 9           
        )
)

and so on....


当将第n个项目分配给结果数组时,请在索引n模源数组长度处添加源项目。 - Michal Klouda
https://dev59.com/rFfUa4cB1Zd3GeqPEhYm#6882417 - Prix
你有什么问题? - Lightness Races in Orbit
可能是重复的问题:在PHP中保留多维数组键的数组排列 - user1646111
4个回答

3
< p > 操作是您的好帮手:
function foo($arr, $n) {
  $result = array();
  for ($i = 0; $i < $n; $i++) {
    $result[$i] = array_map(function($value) use ($i) {
      return $value[$i % count($value)];
    }, $arr);
  }
  return $result;
}

// usage:
var_dump(foo($data, 4));

3

解决这个问题的一个有趣方法是使用MultipleItator()

$iterator = new MultipleIterator;

array_walk($data, function(array $item) use ($iterator) {
    // attach infinite iterators for each element
    $iterator->attachIterator(new InfiniteIterator(new ArrayIterator($item)));
});

它使用InfiniteIterator来在到达末尾时候重置每个数组。这也意味着迭代器整体上是无限的;对其使用foreach会一直进行直到你终止脚本,因此你需要使用for循环:
$iterator->rewind()
for ($i = 0; $i < 4; ++$i) {
    print_r($iterator->current());
    $iterator->next()
}

顺便提一下,你不能在这里使用LimitIterator来选择前四个项目,因为如果你这样做会产生通知。

2
我将把这个操作称为“模块化压缩”,因为它的工作方式类似于Python的zip函数,会回到数组前面。使用数组next函数而不是数值模运算符,这样速度更快。

$array_list应该是一个数组列表;没有进行数据类型检查。

<?php

function zip_modular($len, $array_list) {  
  $out = array();

  for($n = 0; $n < $len; $n++) {
    $out[$n] = array();
    foreach($array_list as &$arr) {
      $cur = current($arr);
      if(empty($cur)) {
        reset($arr);
      }
      $out[$n][] = current($arr);
      next($arr);
    }
  }

  return $out;
}

// example
print_r(zip_modular(4, [[7, 32, 44], [4, 44], [9, 33, 55]]));

/*
Array
(
    [0] => Array
        (
            [0] => 7
            [1] => 4
            [2] => 9
        )

    [1] => Array
        (
            [0] => 32
            [1] => 44
            [2] => 33
        )

    [2] => Array
        (
            [0] => 44
            [1] => 4
            [2] => 55
        )

    [3] => Array
        (
            [0] => 7
            [1] => 44
            [2] => 9
        )

)
*/

使用 http://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list 会更清晰明了。 - Carlos Campderrós
@CarlosCampderrós 可能是这样,尽管并非所有参数都是数组。还需要考虑到 OP 给出的示例输入是一个数组的数组。 - primo

1
尝试这个。
 function sample($len, $array_list) {  
      $out = array();
      //print_r($array_list);

       $num_arrs = count($array_list);


      for($n = 0; $n < $len; $n++) {
        $out[$n] = array();
        for($i = 1; $i <= $num_arrs; $i++) {
            // $array_list['a1'.$i];

          $cur = current($array_list['a'.$i]);
          if(empty($cur)) {
            reset($array_list['a'.$i]);
          }
          $out[$n][] = current($array_list['a'.$i]);
          next($array_list['a'.$i]);
        }
      }

      return $out;
    }

    // example
    print_r(sample(4, $data));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接