配列要素の組み合わせについて

このQ&Aのポイント
  • 配列の要素の組み合わせについて考えています。
  • 特定の前提配列から、子要素の組み合わせを求める関数を作成したいです。
  • どのようにすれば、希望する結果を得ることができるでしょうか?
回答を見る
  • ベストアンサー

配列の要素の組み合わせ

下記のような前提となる配列と、その配列を使った子要素の組み合わせを得られるファンクションを作成しようとしているのですが、なかなかうまく思いつきません。 どのようにしたら可能になりますでしょうか? 【前提】==================== $arr_lst = array( array( 'aaa', 'bbb', ), array( 'AAA', 'BBB', ), array( '111', '222', ), ); 【期待する結果】==================== 'aaa' 'bbb' 'AAA' 'BBB' '111' '222' 'aaa'-'AAA' 'aaa'-'BBB' 'aaa'-'111' 'aaa'-'222' 'bbb'-'AAA' 'bbb'-'BBB' 'bbb'-'111' 'bbb'-'222' 'AAA'-'111' 'AAA'-'222' 'BBB'-'111' 'BBB'-'222' 'aaa'-'AAA'-'111' 'aaa'-'AAA'-'222' 'aaa'-'BBB'-'111' 'aaa'-'BBB'-'222' 'bbb'-'AAA'-'111' 'bbb'-'AAA'-'222' 'bbb'-'BBB'-'111' 'bbb'-'BBB'-'222' 以上、よろしくお願い致します。

  • PHP
  • 回答数3
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • Ogre7077
  • ベストアンサー率65% (170/258)
回答No.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)
回答No.2

表示だけですか? 配列にして返すのかと思った。 とりあえず、組み合わせる数ごとに配列にして返す関数を作ってみる、最終的に全部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)
回答No.1

こんな感じでしょうか? <?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"; } } } } } }

nakayama7
質問者

補足

ありがとうございます。 しかしながら、もっと汎用的なソースがほしいです。。。 4連結も5連結もいけるような。

関連するQ&A

  • 配列の組み合わせを数える方法

    配列の組み合わせを数えるイイ方法はないでしょうか? たとえば ArrayA[]={"aaa","bbb","aaa","ccc","bbb","aaa"} ArrayB[]={"1","1","1","2","1","2"} ↑の配列があるとして、 aaa - 1 : 2個 aaa - 2 : 1個 bbb - 1 : 2個 ccc - 2 : 1個 と組み合わせの数を数えることができる方法で悩んでいます。 Strtusを用いて作成しています。 よろしくお願いします。

    • ベストアンサー
    • Java
  • 配列の要素の値をループ中に変更して確認したいのですが、下記やり方では、

    配列の要素の値をループ中に変更して確認したいのですが、下記やり方では、なぜダメなのでしょうか? $arr = array("値1", "キー1" => "値2", "値3"); foreach($arr as $key => $val){ $arr[$key] = "-{$val}-"; echo $val."<br />"; } foreach($arr as $key => $val){ echo "<br />".$val; } 上のforeachの結果が、下と同じようになると期待したのですが、うまくいきません。 なんで、上のforeachと下のforeachの結果が異なるのでしょうか? foreach文で要素の値が更新されるのは、foreach文が終了した瞬間なのでしょうか。 それとも、値はすぐに更新されているけれども、foreach文の処理(順番に抽出する作業?)は既にスタートしてしまっているので、ループ中に更新されても、途中で反映することはできない、ということなのでしょうか? さっぱり分からないので、誰か教えてください。 「配列の要素の値をループ中に変更して確認したい」というよりは、 「なんで、二つのforeach文で結果が異なるか知りたい」です。

    • ベストアンサー
    • PHP
  • 多次元配列を、1次元の配列にする関数を書いてください。

    以下のように、多次元配列の配列をペチャンコにする関数(array_flatten)ってどうかきますか? <?php $arr[0] = 'a'; $arr[1][0] = 'b'; $arr[1][1][0] = 'c'; $arr[1][1][1][0] = 'd'; $arr[1][1][1][1][0] = 'e'; $arr[1][1][1][2] = 'f'; $arr[1][1][2] = 'g'; $arr[1][2] = 'h'; $arr[2] = 'i'; function array_flatten($arg){   処理; } $new_arr = array_flatten($arr); print_r($new_arr); ?> ↓ Array (   [0] => a   [1] => b   [2] => c   [3] => d   [4] => e   [5] => f   [6] => g   [7] => h   [8] => i ) ※関数のなかで、ペチャンコの配列を格納するための新しい配列を宣言すると、 同関数を再帰的に呼び出したら、その配列が初期化されますよね?

    • ベストアンサー
    • PHP
  • 多次元配列?配列のキー?変数の型?

    PHP勉強中のものです。 予定通りの動作にならんく四苦八苦しています。 どのように修正すれば予定通りになるのか考え方のアドバイスなどお願いします。 処理したいこと 変数$xxxの先頭の文字と最後の文字をsubstr()で取り出し$aaaと$bbbに別けそれぞれ代入しキーとして多次元配列に代入した配列要素を指定してechoで出力したい 試してみたこと $aaa1と$bbb1に直接整数を代入してみたところ、echoで出力された キーになる変数を整数型として変数に代入してみたが希望通りの動作にならなかった。 なにかアドバイス頂けると助かります。 $array = array( "0" =>array("あいうえお","かきくけこ"), "1" =>array("さしすせそ") ); $xxx = "0-1"; $aaa = substr($xxx,0,1); $bbb = substr($xxx,2); $aaa = (int)$aaa; $bbb = (int)$bbb; echo $array[$aaa][$bbb]; //出力されない $aaa1 = 0; $bbb1 = 1; echo $array[$aaa1][$bbb1]; //出力された $aaa = (int)$aaa; $bbb = (int)$bbb; echo $array[$aaa][$bbb]; //出力されない

    • ベストアンサー
    • PHP
  • JavaScriptでオブジェクトの配列

    function myfunc() {} で定義したようなオブジェクトを var arr = new Array(); arr.push()で配列に入れて、あとから取り出す際に arr[0]をmyfunc型として使うにはどうすればよいでしょうか? キャストのようなものも多分なさそうですし。

  • 配列のlengthの意味

    配列を作って以下のように作りました。 ==================================== var arr:Array = new Array(); arr[0] = "地球"; arr[1] = "太陽"; arr[2] = "月" arr["川"] = "rever"; arr["魚"] = "fish" arr["鳥"] = "bird"; trace(arr[0]);  //結果: 地球 trace(arr["魚"]);  //結果: fish trace(arr.length);  //結果: 3 →なぜ6ではない? ==================================== 連想配列3つと、普通の3つの2種類を arrという配列に入れたのですが、 lengthを調べると 3 と出ます。 連想配列というのは、 length には反映されないのでしょうか。 またその場合、連想配列の個数を調べるときは どのように書けばよいのでしょうか。 連想配列って、配列のどこに格納されているのだろう。。? と不思議に思ってしまいます。 ご存知の方いらっしゃいましたら、 何卒よろしくおねがいいたします。

    • ベストアンサー
    • Flash
  • 割り切れなくなるまで分割して配列に入れたい

    <?php make(7); function make($n) { $arr = array($n); $arr_new = division_arr($arr); print_r($arr_new); } function division_arr($arr) { for ($i = 0; $i < count($arr); $i++) { $arr_new[$i] = division($arr[$i]); if ($arr_new[$i][0] > 0) { return division_arr($arr_new[$i]); } else { } } return $arr_new; } function division($n) { $a = $b = floor($n / 2); if ($n % 2 != 0) { $b+=1; } return array($a, $b); } /* array( [3,4], [[1,2],[2,2]], [[0,1],[1,1],[1,1],[1,1]] ); 再帰的に配列を分割していき、最終的にこのような出力にしたいです。 */ ?> 教えて下さい。よろしくお願いいたします。m(_ _)m

    • ベストアンサー
    • PHP
  • 連想配列を配列に入れるには

    下記のような連想配列を配列に入れる簡単な方法はありますか。 array("a"=>"1","b"=>"2") 期待する結果(print_r) Array ( [0] => Array ( "a" => "1" ) [1] => Array ( "b" => "2" ) ) 宜しくお願い致します。

    • ベストアンサー
    • PHP
  • 配列のキー取得

    現在の$str配列には、下記のようになっています。 Array ( [9] => test [5] => aaa [7] => bbb) print_r(array_keys($str)); とすると下記のように配列のキー値がわかりますが、 Array ( [0] => 9 [1] => 5 [2] => 7) キーを下記のように一つづつほかの配列に代入したい場合はどのようにしたらいいのでしょうか? for($i=0;$i<count($str);$i++){ $new_str[$i]=キーを取得する関数; } ご教授お願いいたします。

    • ベストアンサー
    • PHP
  • 配列にポインタを入れたい

    C言語のプログラム作成で全然分からなくて非常に困っています。 そのため教えていただきたく思います。 目的は、 文字列 str="aaa\nbbb\nccc\n" を \n で区切って配列に入れたいです。 文字列は不定長さで str="aa\n" や str="aaa\nbb\nc\nddd\neee\n" などです。 必ず\nで区切られています。 それらを配列に入れて hairetu[0] = "aaa\n" hairetu[1] = "bbb\n" hairetu[2] = "ccc\n" ・・・ という結果を得たいです。 自分でまったく分からないところは、 配列の要素にアドレスを入れること、 文字列strの長さが固定でないため配列の要素をどのように増やすか、 です。 どなたか助けていただけないでしょうか。 直接回答を教えていただけたらすごく助かります。 参考のページや考え方を教えていただいてもありがたいです。 よろしくお願いします。

専門家に質問してみよう