我只是想找出更好的方法来做到这一点:
$array = array(
array('a', 'b', 'c'),
array('e', 'f', 'g'),
array('h', 'i', 'j', 'k', 'l')
);
目标是打印这样的东西:
a e h
a e i
a e j
a e k
a e l
a f h
a f i
a f j
a f k
a f l
a g h
a g i
a g j
a g k
a g l
然后对 b 和 c 做同样的事情。
foreach ($array[0] as $val1) {
foreach ($array[1] as $val2) {
foreach ($array[2] as $val3) {
echo "$val1 $val2 $val3 \n";
}
echo "--------\n";
}
}
我还尝试动态创建上面的代码并使用 eval 执行它:
$eval = '
$data =array();
';
$eval_blocks = '';
$eval_foreach = '';
$eval_data = '
$data[] = ';
$looplength = count($array);
for ($i = 0; $i < $looplength; $i++) {
$eval_foreach .= '
foreach($array[' . $i . '] as $val' . ($i + 1) . '){
';
if (($i + 1) == $looplength) {
$eval_data .= ' $val' . ($i + 1) . ';';
} else {
$eval_data .= ' $val' . ($i + 1) . ' ." ".';
}
$eval_blocks .= '
}
';
}
$eval = $eval . $eval_foreach . $eval_data . $eval_blocks;
eval($eval);
print_r($data);
但如果可能的话,我仍然想找到更好的方法。
更新:
注意:$array是动态的,它可能包含两个或更多的子数组
最佳答案
我尝试了另一种方法,但最终以类似于 Valentin CLEMENT 的解决方案的方法结束,尽管我的函数更加冗长。
尽管如此,该函数的独创性在于它为您提供了一个组合树,这可能(或可能不会)有用,具体取决于您打算做什么。
代码如下:
function getCombinations( $arrayList, $index = 0 )
{
$subCombinations = $combinations = '';
if ( $index < count( $arrayList )-1 )
{
$subCombinations = getCombinations( $arrayList, $index+1 );
}
foreach( $arrayList[$index] as $item )
{
$combinations[$item] = $subCombinations ;
}
return $combinations;
}
$combinations = getCombinations( $array );
print_r( $combinations );
使用示例数据:
$array = array(
array('a', 'b', 'c'),
array('e', 'f', 'g'),
array('h', 'i', 'j', 'k', 'l')
);
它会输出:
Array
(
[a] => Array
(
[e] => Array
(
[h] =>
[i] =>
[j] =>
[k] =>
[l] =>
)
[f] => Array
(
[h] =>
[i] =>
[j] =>
[k] =>
[l] =>
)
[g] => Array
(
[h] =>
[i] =>
[j] =>
[k] =>
[l] =>
)
)
[b] => Array
(
[e] => Array
(
[h] =>
[i] =>
[j] =>
[k] =>
[l] =>
)
[f] => Array
(
[h] =>
[i] =>
[j] =>
[k] =>
[l] =>
)
[g] => Array
(
[h] =>
[i] =>
[j] =>
[k] =>
[l] =>
)
)
[c] => Array
(
[e] => Array
(
[h] =>
[i] =>
[j] =>
[k] =>
[l] =>
)
[f] => Array
(
[h] =>
[i] =>
[j] =>
[k] =>
[l] =>
)
[g] => Array
(
[h] =>
[i] =>
[j] =>
[k] =>
[l] =>
)
)
)
然后它需要额外的代码来绘制预期结果:
function drawCombinations( $combinations, $line = array() )
{
foreach( $combinations as $value => $children )
{
array_push( $line, $value );
if ( is_array( $children ) )
{
drawCombinations( $children, $line );
}
else
{
echo implode( " ", $line ) ." \n";
}
array_pop( $line );
}
}
drawCombinations( $combinations );
产生:
a e h
a e i
a e j
a e k
a e l
a f h
a f i
a f j
a f k
a f l
a g h
a g i
a g j
a g k
a g l
b e h
b e i
b e j
b e k
b e l
b f h
b f i
b f j
b f k
b f l
b g h
b g i
b g j
b g k
b g l
c e h
c e i
c e j
c e k
c e l
c f h
c f i
c f j
c f k
c f l
c g h
c g i
c g j
c g k
c g l
正如我之前所说,如果您不需要这棵结果树(您的问题没有提到,我只是在搜索最佳方法时产生了这个),Valentin CLEMENT 的方法可能会更好(如果您不使用数据集太大,我会在后面解释原因)。
我以一种我认为更具可读性和可用性的方式重写了它:
function expand( $array, $from = 0, $length = false )
{
if ( $length === false )
{
$length = count( $array );
}
if ( $length == $from )
{
return array('');
}
else
{
$result = array();
foreach( $array[$from] as $x )
{
foreach( expand( $array, $from+1, $length ) as $tail )
{
$result[] = trim("$x $tail");
}
}
return $result;
}
}
$combinations = expand( $array );
print_r( $combinations );
它返回以下数组:
Array
(
[0] => a e h
[1] => a e i
[2] => a e j
[3] => a e k
[4] => a e l
[5] => a f h
[6] => a f i
[7] => a f j
[8] => a f k
[9] => a f l
[10] => a g h
[11] => a g i
[12] => a g j
[13] => a g k
[14] => a g l
[15] => b e h
[16] => b e i
[17] => b e j
[18] => b e k
[19] => b e l
[20] => b f h
[21] => b f i
[22] => b f j
[23] => b f k
[24] => b f l
[25] => b g h
[26] => b g i
[27] => b g j
[28] => b g k
[29] => b g l
[30] => c e h
[31] => c e i
[32] => c e j
[33] => c e k
[34] => c e l
[35] => c f h
[36] => c f i
[37] => c f j
[38] => c f k
[39] => c f l
[40] => c g h
[41] => c g i
[42] => c g j
[43] => c g k
[44] => c g l
)
然后很容易达到预期的结果:
echo implode( "\n", $combinations )."\n";
将输出:
a e h
a e i
a e j
a e k
a e l
a f h
a f i
a f j
a f k
a f l
a g h
a g i
a g j
a g k
a g l
b e h
b e i
b e j
b e k
b e l
b f h
b f i
b f j
b f k
b f l
b g h
b g i
b g j
b g k
b g l
c e h
c e i
c e j
c e k
c e l
c f h
c f i
c f j
c f k
c f l
c g h
c g i
c g j
c g k
c g l
一开始我以为我的解决方案比 Valentin 的解决方案消耗更多的内存,因为它使用数组,但当我测试它时,我意识到它确实使用了更少的内存。
针对这两种方法显示内存指标给出了这些结果:
drawCombinations( getCombinations( $array ));
echo memory_get_usage()." ". memory_get_peak_usage()."\n";
// 238736 244896
echo implode( "\n", expand( $array ) )."\n";
echo memory_get_usage()." ". memory_get_peak_usage()."\n";
// 238912 252304
但是当使用更大的输入值时它变得更加重要,其中:
$array = array(
array('a', 'b', 'c'),
array('e', 'f', 'g'),
array('h', 'i', 'j', 'k', 'l'),
array('m', 'n', 'o', 'p', 'q', 'r', 's'),
array('t', 'u', 'v', 'x', 'y', 'z')
);
getCombinations 给出:
drawCombinations( getCombinations( $array ));
echo memory_get_usage()." ". memory_get_peak_usage()."\n";
// 242376 253008
展开给出:
echo implode( "\n", expand( $array ) )."\n";
echo memory_get_usage()." ". memory_get_peak_usage()."\n";
//242544 704520
如果我们查看每个函数生成的数组,原因就很明显了,因为第一个解决方案存储的重复值较少(我不确定 PHP 如何处理结束树的每个分支的重复数组)。
再一次,取决于你打算实现什么,你会关心与否。
动态“回显”每一行而不是创建一个大的结果数组会稍微减少内存峰值问题,但随着数据集的增长,expand() 仍然会消耗更多内存。
我希望它能有所帮助,至少那对我来说很有趣;)
关于PHP 数组 : join each sub-array together (Probability),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17959127/
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作
我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>
我正在尝试按0-9和a-z的顺序创建数字和字母列表。我有一组值value_array=['0','1','2','3','4','5','6','7','8','9','a','b','光盘','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','','u','v','w','x','y','z']和一个组合列表的数组,按顺序,这些数字可以产生x个字符,比方说三个list_array=[]和一个当前字母和数字组合的数组(在将它插入列表数组之前我会把它变成一个字符串,]current_combo['0','0','0']
查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用