- ベストアンサー
配列要素の組み合わせについて
- 配列の要素の組み合わせについて考えています。
- 特定の前提配列から、子要素の組み合わせを求める関数を作成したいです。
- どのようにすれば、希望する結果を得ることができるでしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
class Combin { protected $result; protected $datas; protected $num; function __construct($datas) { $this->datas = $datas; } function select($num) { $this->result = array(); $this->num = $num; $this->recursive(array(), 0); return $this->result; } function recursive($buff, $index) { if (count($buff) == $this->num) { $this->result[] = implode('-', $buff); return; } for($i = $index; $i < count($this->datas); $i++) { foreach($this->datas[$i] as $v) { $this->recursive(array_merge($buff, (array)$v), $i+1); } } } } $arr_lst = array( array('aaa','bbb') ,array('AAA','BBB') ,array('111','222') ); $obj = new Combin($arr_lst); print_r($obj->select(1)); print_r($obj->select(2)); print_r($obj->select(3));
その他の回答 (2)
- mpro-gram
- ベストアンサー率74% (170/228)
表示だけですか? 配列にして返すのかと思った。 とりあえず、組み合わせる数ごとに配列にして返す関数を作ってみる、最終的に全部mergeして表示すれば? <?php /* 最初の1要素の羅列= 一次元に変換は array_merge で十分 でしょう // 要素数不定なら、ループで merge */ function singler($arr){ if( ! is_array($arr) || empty($arr) ){ return false; } $result = $arr[0]; $len = count($arr); for($i=1; $i<$len; $i++){ $result = array_merge($result, $arr[$i]); } return $result; } /* 2つの配列の各要素を取り出して組み合わせて、文字列にする @param $a,$b ; 空ではない配列 @return array , もし、引数に空配列や配列ではないものが混じっていたら返値はfalse */ function comb2($a, $b){ if( !is_array($a) || !is_array($b) || empty($a) || empty($b) ){ return false; } $result = array(); foreach($a as $v1){ foreach($b as $v2){ $result[] = $v1 . "'-'" .$v2 ; } } return $result; } /* 3つの配列の各要素を取り出して組み合わせたものを文字列にする @param $a,$b,$c ; 空ではない配列 @return array (要素数=組み合わせの数、引数の各要素数の積) もし、引数に空配列や配列ではないものが混じっていたら返値はfalse */ function comb3($a, $b, $c){ if( !is_array($a) || !is_array($b) || !is_array($c) || empty($a) || empty($b) || empty($c) ){ return false; } $result = array(); foreach($a as $v1){ foreach($b as $v2){ foreach($c as $v3){ $result[] = $v1 . "'-'" . $v2 ."'-'". $v3 ; } } } return $result; } // 4つ以上 を連結するのは、comb2, comb3 を参考に個数ごとに作成して下さい // 全部一次元にしたところで、表示用関数 function show($arr){ foreach($arr as $val){ echo "'". $val , "'<br>\n"; } } // 上記を呼び出して最終形作成関数 function array_combinater($arr_list){ $d = singler($arr_list); $len = count($arr_lst) ; for($i=0; $i<$len-1; $i++){ for( $i=$i; $j<$len; $j++){ $d = array_merge($d ,comb2($arr_lst[$i], $arr_lst[$j]) ); } } if($len>2){ for($i=0; $i<$len-2; $i++){ for( $j=$i; $j<$len-1; $j++){ for( $k=$j; $k<$len; $k++){ $d = array_merge($d, com3( $arr_lst[$i], $arr_lst[$j], $arr_lst[$k]) ); } } } } // if($len>3){ 4個用関数呼び出し } show($d); }
- yambejp
- ベストアンサー率51% (3827/7415)
こんな感じでしょうか? <?php $arr_lst = array( array('aaa','bbb') ,array('AAA','BBB') ,array('111','222') ); //単純表示 for($i=0;$i<count($arr_lst);$i++){ for($j=0;$j<count($arr_lst[$i]);$j++){ print "'{$arr_lst[$i][$j]}'<br>\n"; } } //2連結表示 for($i=0;$i<count($arr_lst);$i++){ for($j=0;$j<count($arr_lst[$i]);$j++){ for($k=$i+1;$k<count($arr_lst);$k++){ for($l=0;$l<count($arr_lst[$l]);$l++){ print "'{$arr_lst[$i][$j]}'-'{$arr_lst[$k][$l]}'<br>\n"; } } } } //3連結表示 for($i=0;$i<count($arr_lst);$i++){ for($j=0;$j<count($arr_lst[$i]);$j++){ for($k=$i+1;$k<count($arr_lst);$k++){ for($l=0;$l<count($arr_lst[$l]);$l++){ for($m=$k+1;$m<count($arr_lst);$m++){ for($n=0;$n<count($arr_lst[$m]);$n++){ print "'{$arr_lst[$i][$j]}'-'{$arr_lst[$k][$l]}'-'{$arr_lst[$m][$n]}'<br>\n"; } } } } } }
補足
ありがとうございます。 しかしながら、もっと汎用的なソースがほしいです。。。 4連結も5連結もいけるような。