以下のようなPHPの多次元配列があります。

検索対象のnameが「国語」なら”勉強は国語”と表示し、
「読書」なら”勉強は国語で読書”と表示したいのですが、出力が上手くできません。
(接続助詞を付けるのが無理ならカンマやハイフン等でも構いません)

目的の結果を得られるコードを書いてくれた方には、500pt差し上げます。
(分からない方や質問の根本を正そうとする方は回答しないでください)

$array = array(
'1' => array(
'name' => '勉強',
'child' => array(
'2' => array(
'name' => '国語',
'child' => array(
'3' => array('name' => '読書'),
'4' => array('name' => '作文'),
),
),
),
),
'5' => array('name' => '遊び')
);

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2011/07/01 23:35:34
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:TransFreeBSD No.2

回答回数668ベストアンサー獲得回数268

ポイント500pt

Cherenkovさんの配列いただきました。

http://codepad.org/hvi1b14B


<?php
$array = array(
	'1' => array(
		'name' => '勉強',
		'post' => '',
		'child' => array(
			'2' => array(
				'name' => '国語',
				'post' => '',
				'child' => array(
					'3' => array('name' => '読書'),
					'4' => array('name' => '作文'),
				),
			),
		),
	),
	'5' => array('name' => '遊び')
);

function search_name($arr, $name)
{
	foreach ($arr as $val) {
		if ($val["name"] == $name)
			return $name;
		if (array_key_exists("child", $val)) {
			$ret = search_name($val["child"], $name);
			if ($ret != "")
				return $val["name"] . $val["post"] . $ret;
		}
	}
	return "";
}

echo search_name($array, "読書");
?>

foreacheで出力して再帰しながらnameが一致する配列を探す

までわかってるなら

  • foreachでこの階層を探す
    • nameが一致したら再帰終了
      • 探す文字列が必要なので引数にする
    • childがあったら再帰で下の階層を探す
      • 配列を引数にする
      • 再帰で見つかったら再帰終了
      • 見つからなかったら次
  • 配列中に見つからなかったら再帰終了
    • 見つからなかったことが分かるような戻り値が必要
  • 以上を再帰関数に
  • 戻り値は配列(および空の配列)か生成した文字列(および空文字)
    • 判定は空文字の方が楽そう
    • 拡張するならクラス化して戻り値をオブジェクトの配列に

[追記]

これ、質問で表示について詳しく触れていますが、表示や出力の問題ではなくて、フラットでない多次元配列内をたどって必要な値を見つけ出す方法が問題なのですよね。

出力できないと聞くのではなく、値を探し出す方法を考えるべきでした。表示を中心に考えているから、コードが見えこず、質問の趣旨もぼけてしまったのだと思いました。こういう小さいのでもMVCを意識すると良いですよ。

#ちなみにこれも「質問の根本を正そうとする」ことでしょうか。しかし、根本も大事だと思いますよ。

id:k27w

ありがとうございます。回答は思い通りでした。

あと、回答いただいたのに反論して申し訳ありませんが、質問の投稿文には限りがあります。

1から10まで説明して、こちらが困っている事を事細かに書けばより求める答えを導き出せるかもしれません。しかし、現実的にそこまで詳しく書くと、はてなに投稿出来る文字数や範囲では納まりませんよね?

私が言った「根本~」というのは、過去に「その質問をして意味があるのですか?」と言った事を聞いてくる回答者が多かったからです。こちらは悩んでいるから質問するわけで、質問の必要性を説いているのではありません。出来るか否かを教えて欲しいから質問しているのです。

根本的な配列の考え方、出力方法、なぜそれをするのか?と言った”理由”があるのも事実でしょうが、冒頭に書いたように、それを1から10まで説明するわけにも行きません。ですから、質問文から読みとっていただき、回答していただける方のみ回答していただくというのが、こういうQ&Aサイトの仕組みではないでしょうか。

最初の回答者様は単なる配列の出力方法を提示していますが、多次元配列のコードを提示する人間が、配列の基本的な出力方法(echoやprint)を知らないわけないと思うのですが。

それこそMVCまで言い出すと、例題のコードももっと長くなり、こちらは回答者様が答えやすい・完璧なコードを提示する必要がありますが、それが出来たらそもそも質問しないですよね。ですから、自分が必要な・分からない箇所のみ質問させていただきました。

教えていただいたコード参考にさせていただきます。ありがとうございました。

2011/07/01 23:35:24

その他の回答1件)

id:Cherenkov No.1

回答回数1504ベストアンサー獲得回数493

http://codepad.org/SQmQQbIP

<?php
$array = array(
	'1' => array(
		'name' => '勉強',
		'child' => array(
			'2' => array(
				'name' => '国語',
				'child' => array(
					'3' => array('name' => '読書'),
					'4' => array('name' => '作文'),
				),
			),
		),
	),
	'5' => array('name' => '遊び')
);

//勉強は国語
echo $array['1']['name'] . '' . $array['1']['child']['2']['name'];

//勉強は国語で読書
echo $array['1']['name'] . '' . $array['1']['child']['2']['name'] . '' . $array['1']['child']['2']['child']['3']['name'];
?>

多次元配列と変数の関係を正しく理解していますか?

>検索対象のname

の意味がわからないので、取りあえず上の多次元配列を使った出力を書いてみました。



id:k27w

それは単に配列を指定して出力してるだけですよね?

質問文をきちんと読んで下さい。「検索対象のnameが」と書いています。

foreacheで出力して再帰しながらnameが一致する配列を探す方法もあると思いますが、具体的なコードが分からないので質問しています。配列の根本が理解できていないから質問しているのではありません。

2011/07/01 20:41:36
id:TransFreeBSD No.2

回答回数668ベストアンサー獲得回数268ここでベストアンサー

ポイント500pt

Cherenkovさんの配列いただきました。

http://codepad.org/hvi1b14B


<?php
$array = array(
	'1' => array(
		'name' => '勉強',
		'post' => '',
		'child' => array(
			'2' => array(
				'name' => '国語',
				'post' => '',
				'child' => array(
					'3' => array('name' => '読書'),
					'4' => array('name' => '作文'),
				),
			),
		),
	),
	'5' => array('name' => '遊び')
);

function search_name($arr, $name)
{
	foreach ($arr as $val) {
		if ($val["name"] == $name)
			return $name;
		if (array_key_exists("child", $val)) {
			$ret = search_name($val["child"], $name);
			if ($ret != "")
				return $val["name"] . $val["post"] . $ret;
		}
	}
	return "";
}

echo search_name($array, "読書");
?>

foreacheで出力して再帰しながらnameが一致する配列を探す

までわかってるなら

  • foreachでこの階層を探す
    • nameが一致したら再帰終了
      • 探す文字列が必要なので引数にする
    • childがあったら再帰で下の階層を探す
      • 配列を引数にする
      • 再帰で見つかったら再帰終了
      • 見つからなかったら次
  • 配列中に見つからなかったら再帰終了
    • 見つからなかったことが分かるような戻り値が必要
  • 以上を再帰関数に
  • 戻り値は配列(および空の配列)か生成した文字列(および空文字)
    • 判定は空文字の方が楽そう
    • 拡張するならクラス化して戻り値をオブジェクトの配列に

[追記]

これ、質問で表示について詳しく触れていますが、表示や出力の問題ではなくて、フラットでない多次元配列内をたどって必要な値を見つけ出す方法が問題なのですよね。

出力できないと聞くのではなく、値を探し出す方法を考えるべきでした。表示を中心に考えているから、コードが見えこず、質問の趣旨もぼけてしまったのだと思いました。こういう小さいのでもMVCを意識すると良いですよ。

#ちなみにこれも「質問の根本を正そうとする」ことでしょうか。しかし、根本も大事だと思いますよ。

id:k27w

ありがとうございます。回答は思い通りでした。

あと、回答いただいたのに反論して申し訳ありませんが、質問の投稿文には限りがあります。

1から10まで説明して、こちらが困っている事を事細かに書けばより求める答えを導き出せるかもしれません。しかし、現実的にそこまで詳しく書くと、はてなに投稿出来る文字数や範囲では納まりませんよね?

私が言った「根本~」というのは、過去に「その質問をして意味があるのですか?」と言った事を聞いてくる回答者が多かったからです。こちらは悩んでいるから質問するわけで、質問の必要性を説いているのではありません。出来るか否かを教えて欲しいから質問しているのです。

根本的な配列の考え方、出力方法、なぜそれをするのか?と言った”理由”があるのも事実でしょうが、冒頭に書いたように、それを1から10まで説明するわけにも行きません。ですから、質問文から読みとっていただき、回答していただける方のみ回答していただくというのが、こういうQ&Aサイトの仕組みではないでしょうか。

最初の回答者様は単なる配列の出力方法を提示していますが、多次元配列のコードを提示する人間が、配列の基本的な出力方法(echoやprint)を知らないわけないと思うのですが。

それこそMVCまで言い出すと、例題のコードももっと長くなり、こちらは回答者様が答えやすい・完璧なコードを提示する必要がありますが、それが出来たらそもそも質問しないですよね。ですから、自分が必要な・分からない箇所のみ質問させていただきました。

教えていただいたコード参考にさせていただきます。ありがとうございました。

2011/07/01 23:35:24

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません