- ベストアンサー
2次元配列を多次元配列にする方法
- PHP5で2次元配列を多次元配列にする方法について教えてください。
- 2次元配列を多次元配列にするためには、関数の再帰呼び出しを使用します。
- 具体的な処理方法は、2次元配列のキーごとの内容を共通項にまとめて、多次元配列に変換することです。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
関数の再帰呼び出しでは有りませんが、以下程度の処理では如何でしょう <?php $a = array( array("one" => "あ", "two" => "う", "three" => "き") ,array("one" => "あ", "two" => "う", "three" => "く") ,array("one" => "あ", "two" => "え", "three" => "け") ,array("one" => "あ", "two" => "え", "three" => "こ") ,array("one" => "い", "two" => "お", "three" => "さ") ,array("one" => "い", "two" => "お", "three" => "し") ,array("one" => "い", "two" => "か", "three" => "す") ,array("one" => "い", "two" => "か", "three" => "せ") ); $result=array(); foreach($array as $t){ $x=array(); $x[]=array_pop($t); while(count($t)>0){ $x[array_pop($t)]=$x; array_shift($x); } $result = array_merge_recursive($result,$x); } print_r($result); ?>
その他の回答 (4)
- __vv00vv__
- ベストアンサー率72% (27/37)
二次元配列であらわされたデータをツリー構造にするという課題という理解でよろしいのでしょうか。 「何次元になるか分からない」ということですが、ことなる要素数の配列がある場合にも 適用できるコードを考えてみました。ただし、ご要望のものとは少々ちがって、各配列の最後のデータも キーとして扱うものです。 <?php $arr = array ( array('one'=>'あ', 'two'=>'か', 'three'=>'さ', 'four'=>'た', 'five'=>'な'), array('one'=>'あ', 'two'=>'か', 'three'=>'さ', 'four'=>'た', 'five'=>'に'), array('one'=>'あ', 'two'=>'か', 'three'=>'し', 'four'=>'た'), array('one'=>'あ', 'two'=>'か', 'three'=>'し', 'four'=>'ち'), array('one'=>'あ', 'two'=>'か', 'three'=>'す', 'four'=>'た'), array('one'=>'あ', 'two'=>'き', 'three'=>'さ'), array('one'=>'い', 'two'=>'か', 'three'=>'さ', 'four'=>'た'), ); $data = array(); foreach($arr as $row) { $tmp =& $data; //参照渡しを使う foreach($row as $item) { if(!isset($tmp[$item])) $tmp[$item] = null; $tmp =& $tmp[$item]; //参照渡しを使う } unset($tmp); } var_dump($data); 出力結果は次のようになります。 array(2) { ["あ"]=> array(2) { ["か"]=> array(3) { ["さ"]=> array(1) { ["た"]=> array(2) { ["な"]=> NULL ["に"]=> NULL } } ["し"]=> array(2) { ["た"]=> NULL ["ち"]=> NULL } ["す"]=> array(1) { ["た"]=> NULL } } ["き"]=> array(1) { ["さ"]=> NULL } } ["い"]=> array(1) { ["か"]=> array(1) { ["さ"]=> array(1) { ["た"]=> NULL } } }
- smileeeen
- ベストアンサー率70% (21/30)
あまり綺麗でない気もしますが、下記のような形でも実装できました。 関数に渡される内部の配列は要素数が全て同一であるという前提です。 $a = array( array("one" => "あ", "two" => "う", "three" => "き") ,array("one" => "あ", "two" => "う", "three" => "く") ,array("one" => "あ", "two" => "え", "three" => "け") ,array("one" => "あ", "two" => "え", "three" => "こ") ,array("one" => "い", "two" => "お", "three" => "さ") ,array("one" => "い", "two" => "お", "three" => "し") ,array("one" => "い", "two" => "か", "three" => "す") ,array("one" => "い", "two" => "か", "three" => "せ") ); $rtn = func($a); print_r($rtn); function func($a) { $tmp = array(); $out = array(); foreach ($a as $arr) { $put = array_shift($arr); if (count($arr) === 0) { if (!in_array($put, $out)) { $out[] = $put; } } else { $tmp[$put][] = $arr; } } if (count($out) === 0) { foreach ($tmp as $key => $value) { $out[$key] = func($value); } } return $out; } (※インデントのために全角スペースを使っています)
- himajin100000
- ベストアンサー率54% (1660/3060)
===================Q5861563-1.php050302================== <?php function main(){ /* 辞書順にソートされているものとする */ /* 連想配列の時もそんなに難しくはないとは思うけど、面倒なので省略 */ /* Unicodeのコードポイント順で比較したいんですが、strcmpってそういう挙動します? 1バイトずつ並び替えてたらどうしよう。うまいサンプル知らないんだよね…。 */ $a=array( array("あ", "う", "き") ,array("あ", "う", "く") ,array("あ", "え", "け") ,array("あ", "え", "こ") ,array("い", "お", "さ") ,array("い", "お", "し") ,array("い", "か", "す") ,array("い", "か", "せ") ); header("Content-Type:text/plain"); print_r(rec($a,0)); } function rec($x,$p){ if(count($x,COUNT_NORMAL) === 1){ return $x; } while(count($x,COUNT_NORMAL) > 0){ $s = $x[0][0]; $y = array(); while(count($x,COUNT_NORMAL) !== 0){ if(strcmp($x[0][0],$s) !== 0 ){ break; } array_splice($x[0],0,1,NULL); $y[] = $x[0]; array_splice($x,0,1,NULL); } $retval[$s] = rec($y,$p+1); } return $retval; } main(); ?> ===== 出力結果 (見づらければユーザースタイルシート当てるなり、 教えてgooやOKWaveの回答のソースを見て判断して。 全角空白とかで代用するの嫌いなんで) ============ Array ( [あ] => Array ( [う] => Array ( [き] => Array ( [0] => Array ( ) ) [く] => Array ( [0] => Array ( ) ) ) [え] => Array ( [け] => Array ( [0] => Array ( ) ) [こ] => Array ( [0] => Array ( ) ) ) ) [い] => Array ( [お] => Array ( [さ] => Array ( [0] => Array ( ) ) [し] => Array ( [0] => Array ( ) ) ) [か] => Array ( [す] => Array ( [0] => Array ( ) ) [せ] => Array ( [0] => Array ( ) ) ) ) )
- yambejp
- ベストアンサー率51% (3827/7415)
2次元配列ならさらっとforeachでやればいいような・・・ <? $a=Array( array("one" => "あ", "two" => "う", "three" => "き") ,array("one" => "あ", "two" => "う", "three" => "く") ,array("one" => "あ", "two" => "え", "three" => "け") ,array("one" => "あ", "two" => "え", "three" => "こ") ,array("one" => "い", "two" => "お", "three" => "さ") ,array("one" => "い", "two" => "お", "three" => "し") ,array("one" => "い", "two" => "か", "three" => "す") ,array("one" => "い", "two" => "か", "three" => "せ") ); foreach($a as $data){ $b[$data["one"]][$data["two"]][]=$data["three"]; } print "<pre>\n"; print_r( $b); print "</pre>"; ?>
補足
説明不足で申し訳ないです。 3次元までなら上のやり方でもいいのですが、 何次元になるか分からない場合は、上の方法では無理です。 あと、同じキーの共通項目をまとめたいです。
お礼
どうも、ありがとうございます。 とても美しいコードですね。 参考にさせていただきました。