我在创建多变量测试的配方时遇到了问题。例如,如果我想测试一套服装,我有3种不同的帽子,衬衫和裤子。我想列出它们的所有可能组合而不重复。到目前为止,这是我的思考过程:
// outfit #1
$outfit[0][0] = "hat A ";
$outfit[0][1] = "shirt A ";
$outfit[0][2] = "pants A ";
// outfit #2
$outfit[0][0] = "hat B ";
$outfit[0][1] = "shirt B ";
$outfit[0][2] = "pants B ";
// outfit #3
$outfit[0][0] = "hat C ";
$outfit[0][1] = "shirt C ";
$outfit[0][2] = "pants C ";
function recipeMaker()
{
$i = 0;
$j = 0;
foreach ($outfit as $outfit_2)
{
foreach ($outfit_2 as $outfit_3)
{
...some magic here...
recipe[$i][$j] = ...something goes here...
$j++;
}
$i++;
}
}
foreach ($recipe as $r)
{
echo $r . "<br />";
}
然后输出:
hat A shirt A pants A
hat B shirt A pants A
hat C shirt A pants A
hat A shirt B pants A
etc.
答案 0 :(得分:1)
你可以沿着嵌套foreach
循环的路线走下去,但是当你想要扩展服装时会发生什么(例如添加一个关系列表)?这是一个解决方案,可以输出任意数量的集合中可用的组合:
class Combiner {
protected $_collections;
protected $_combinations;
public function __construct() {
$args = func_get_args();
if (count(array_filter(array_map('is_array', $args))) !== func_num_args()) {
throw new Exception('Can only pass array arguments');
}
$this->_collections = $args;
}
protected function _getBatch(array $batch, $index) {
if ($index < count($this->_collections)) {
foreach ($this->_collections[$index] as $element) {
// get combinations of subsequent collections
$this->_getBatch(array_merge($batch, array($element)), $index + 1);
}
} else {
// got a full combination
$this->_combinations[] = $batch;
}
}
public function getCombinations() {
if (null === $this->_combinations) {
$this->_getBatch(array(), 0);
}
return $this->_combinations;
}
}
$hats = array('Hat A', 'Hat B', 'Hat C');
$shirts = array('Shirt A', 'Shirt B', 'Shirt C');
$pants = array('Pants A', 'Pants B', 'Pants C');
$combiner = new Combiner($hats, $shirts, $pants);
var_dump($combiner->getCombinations());
它沿着类型列表移动并选择一个(比如说帽子A),然后递归地构建与该项目一起使用的其他类型的组合。要添加新类型,就像将另一个参数传递给构造函数一样简单。
答案 1 :(得分:0)
首先,将您的阵列安排到类似的内容中(即一个阵列中的所有帽子,另一个阵列中的所有衬衫等)以获得此内容:
$hats[0] = 'Hat A';
$hats[1] = 'Hat B';
$hats[2] = 'Hat C';
$shirts[0] = 'Shirt A';
$shirts[1] = 'Shirt B';
$shirts[2] = 'Shirt C';
$pants[0] = 'Pants A';
$pants[1] = 'Pants B';
$pants[2] = 'Pants C';
$recipe = array();
然后使用foreach构造循环遍历每个元素,如下所示:
foreach ($hats as $hat) {
foreach ($shirts as $shirt) {
foreach ($pants as $pant) {
$recipe = $hat." ".$shirt." ".$pant;
}
}
}
foreach ($recipe as $r) {
echo $r."<br>";
}