人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

2chのレスをアンカで並びかえる
→http://d.hatena.ne.jp/Gemma/20091021/1256138200

を見てPHPで書き換えてますが、わからないことがあって困ってます。


下記の方法は参考URLを元に、1次元配列のキーをレスNoとして、値をレスアンカーとして、
未来へのアンカーを含まない配列を生成しています。

removeFutureAnchor($array_data);

function removeFutureAnchor($array_data) {
return array_map(
function ($input) {
return array_filter($input, function($values) {
return $values < $array_keys($values);
}
);
}

, $array_data);
}


上記の方法を、下記のような形式の2次元の連想配列で行なうことを考えています。
1次元配列と2次元の連想配列でやり方が違うのかわからなくて質問させて頂きました。

何か良い方法はないでしょうか?

$array_datas[] = array(
'res_no' => 'レスNo',
'name' => '名前',
'res_anchor' => 'レスアンカー',
'res' => 'レス文'
); // $array_datas[]のキーと 'res_no' => 'レスNo' は合わせてあります。

removeFutureAnchor($array_datas['res_anchor']);


よろしくお願いします。

●質問者: pochi1234
●カテゴリ:コンピュータ ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● oil999
●0ポイント

ご質問のリンク先のプログラムは、ツリー構造を1次元配列で表現しているので、2次元連想配列で処理することはできません。

【参考】配列

http://php.s3.to/man/language.types.array.html

2分木を使うと並べ替えも簡単にできます。
http://www.phppro.jp/qa/1349?sort=desc


pochi1234さんのコメント
ご回答ありがとうございます。質問の内容が間違ってました。 1次元の連想配列です。値として連想配列がはいっているので、 配列のネストが正しいかもです。 配列のネストと2次元配列はたぶん違うのかなとふと思いました。

oil999さんのコメント
質問にある $array_datas[] は2次元配列ですよ。 連想配列は要素が文字列になるというだけで、次元は1つと数えます。

pochi1234さんのコメント
1次元配列の値となる部分に 配列をネストして入れたいのですが、 上記の方法が間違っているのか無理なのでしょうか?

oil999さんのコメント
配列のネストという意味が分からないのですが、ご質問の方法では2次元配列になります。

2 ● TransFreeBSD
●300ポイント ベストアンサー

データ構造に不明な点があります。できればデータをあてはめた例を例示してください。
#というかデータ構造がはっきりできないから処理もかけないのだと思った。

データ構造が元の2次元配列の個々のレスアンカーの値が連想配列になった3次元配列(レス配列×レスアンカー配列×レスアンカーデータ連想配列)の場合
名前とレス文の持たせ方変えればまあ妥当?

<?php
function removeFutureAnchor($array_data) {
 return array_map(function ($input) {
 return array_filter($input, function($values) {
 return $values['res_anchor'] < $values['res_no'];
 });
 }, $array_data);
}

データ構造がそれぞれのレスアンカーのデータを連想配列に収めたレスアンカーデータ連想配列の配列(レスアンカー配列)できている2次元配列(レスアンカー配列×レスアンカーデータ連想配列)の場合
場合によってはこれでも。DB的。でも名前とレス文が。

<?php
function removeFutureAnchor($array_data) {
 return array_filter($array_data, function($values) {
 return $values['res_anchor'] < $values['res_no'];
 });
}

データ構造が元のレスアンカー配列を収めたレス配列の代わりに、レスアンカー配列を持つレスデータ連想配列の配列(レス配列)という3次元配列(レス配列×レスデータ連想配列×レスアンカー配列)の場合
クロージャが必要?というかこうする意味ある?

<?php
function removeFutureAnchor($array_data) {
 return array_map(function ($input) {
 $res_no = $input['res_no'];
 return array_filter($input['res_anchor'], function($values) use($res_no) {
 return $values < $res_no;
 });
 }, $array_data);
}

というか、そもそものところで謎が。


pochi1234さんのコメント
ご回答ありがとうございます。 ご指摘の通り、もともとのコードも2次元配列で、元々のデータ構造がはっきりしていませんでした。 使用したいレス配列は次の通りです。 1次配列のキーを合わせる必要がありませんでしたのでなくしました。 連想配列のレスアンカーのみ、レスアンカーの配列になっています。 $array_data = [ ['res_no' => 1, 'res_anchor' => [], 'res' => 'レス文'], ['res_no' => 2, 'res_anchor' => [1], 'res' => 'レス文'], ['res_no' => 3, 'res_anchor' => [], 'res' => 'レス文'], ['res_no' => 4, 'res_anchor' => [2, 5], 'res' => 'レス文'], // 未来へのアンカー ['res_no' => 5, 'res_anchor' => [1], 'res' => 'レス文'] ] 配列の構成は レス配列×レスデータ連想配列 (レスアンカーはさらに配列) 例えば 4番のレスは $array_data[3]['res_no' => 4, 'res_anchor' => [2, 5], 'res' => 'レス文'] これはお恥かしいですが、2次元配列なのか3次元配列なのか理解できていなく。 処理的には、 レスアンカーの配列のmaxに未来へのアンカーが含まれていたら そのレスを削除するか、未来へのアンカーのみ削除のどちらかにしようと考えています。 return文でご指摘の通りの方法をしたいと思っています。 return $values['res_anchor'] < $values['res_no'];

TransFreeBSDさんのコメント
>|| return $values['res_anchor'] < $values['res_no']; ||< $values['res_anchor']は配列なので比較出来ません。 3番目の方法になりますね。ってちょっと間違えてた。 http://ideone.com/hMbnDM こんな感じ? というか、array_mapとか使わず単純にforで回した方がわかりやすかったりするかも。 というか、クラスにすべきかも?

pochi1234さんのコメント
ありがとうございます。希望していた動作になりました。 たしかにfor文の方がわかりやすいかもしれないですが、 array_map()って複雑な感じがするけど、配列の各要素に対して処理するので 便利かなと思います。 レスアンカーの配列とレスNoは、比較できないですが、 array_filterのinputは配列でもOKなので、 レスアンカーの配列の値1つずつに対して比較できていますね。 useを使うのポイント?かなと思います。

pochi1234さんのコメント
array_mapで配列の要素1つずつ処理してるから res_noを1つずつ処理できているんですね。useは無名関数にスコープ外を変数を使うという宣言ですね。 よく理解できました。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ