PHP5の配列の質問です。


以下3つの多次元配列を、配列Dのようにする方法を知りたいです。
配列Dは日付で降順にソートします。


配列A
text01,text02,date
aaa,00a,2007-01-31 12:00:00
bbb,00b,2007-02-31 12:00:00

配列B
text01,text02,date
eee.00e,2007-05-31 12:00:00
fff,00f,2007-06-31 12:00:00

配列C
text01,text02,date
hhh,00h,2007-03-31 12:00:00
iii,00i,2007-04-31 12:00:00

合体した配列D
text01,text02,date
fff,00f,2007-06-31 12:00:00
eee.00e,2007-05-31 12:00:00
iii,00i,2007-04-31 12:00:00
hhh,00h,2007-03-31 12:00:00
bbb,00b,2007-02-31 12:00:00
aaa,00a,2007-01-31 12:00:00

よろしくお願いします。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2007/10/27 16:37:39
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:GEN111 No.2

回答回数472ベストアンサー獲得回数58

ポイント50pt

eee.00e,2007-05-31 12:00:00

ここの「eee」の後ろのピリオドはカンマに変えました。

$t[0] = 'text01,text02,date
aaa,00a,2007-01-31 12:00:00
bbb,00b,2007-02-31 12:00:00' ;

$t[1] = 'text01,text02,date
eee,00e,2007-05-31 12:00:00
fff,00f,2007-06-31 12:00:00' ;

$t[2] = 'text01,text02,date
hhh,00h,2007-03-31 12:00:00
iii,00i,2007-04-31 12:00:00' ;

foreach($t as $i => $v) {
  foreach($a[$i] = split("\n", $v) as $n => $c)
    $a[$i][$n] = split(',', $a[$i][$n]) ;
}

$D = array_merge($a[0], $a[1], $a[2]) ;
usort($D, 
      create_function(
        '$a, $b',
        'if ($a[2] == $b[2]) return 0 ;
         else return $a[2] < $b[2] ? 1 : -1 ;')) ;
array_shift($D) ; array_shift($D) ;

print_r($D) ;
id:seadwell

ご指導ありがとうございます。

スイマセンm(_ _)m

誤字がありましたね^^;

まだ、よく解っていませんが早速試してみます。

お返事は、理解するまで少し遅くなるかもしれません。

2007/10/26 20:26:45

その他の回答2件)

id:minkpa No.1

回答回数4178ベストアンサー獲得回数55

http://q.hatena.ne.jp/1178209752

こちらに同様の質問と回答がありました。

id:seadwell

チョット解りません。

まず、合体する方法がわかりません。

それに、SQLは使いませんし、ソートに関する記述も見当たりません。

2007/10/26 18:39:21
id:GEN111 No.2

回答回数472ベストアンサー獲得回数58ここでベストアンサー

ポイント50pt

eee.00e,2007-05-31 12:00:00

ここの「eee」の後ろのピリオドはカンマに変えました。

$t[0] = 'text01,text02,date
aaa,00a,2007-01-31 12:00:00
bbb,00b,2007-02-31 12:00:00' ;

$t[1] = 'text01,text02,date
eee,00e,2007-05-31 12:00:00
fff,00f,2007-06-31 12:00:00' ;

$t[2] = 'text01,text02,date
hhh,00h,2007-03-31 12:00:00
iii,00i,2007-04-31 12:00:00' ;

foreach($t as $i => $v) {
  foreach($a[$i] = split("\n", $v) as $n => $c)
    $a[$i][$n] = split(',', $a[$i][$n]) ;
}

$D = array_merge($a[0], $a[1], $a[2]) ;
usort($D, 
      create_function(
        '$a, $b',
        'if ($a[2] == $b[2]) return 0 ;
         else return $a[2] < $b[2] ? 1 : -1 ;')) ;
array_shift($D) ; array_shift($D) ;

print_r($D) ;
id:seadwell

ご指導ありがとうございます。

スイマセンm(_ _)m

誤字がありましたね^^;

まだ、よく解っていませんが早速試してみます。

お返事は、理解するまで少し遅くなるかもしれません。

2007/10/26 20:26:45
id:y-kawaz No.3

回答回数1422ベストアンサー獲得回数226

ポイント50pt

こんな感じですかね。

  1. array_mergeで配列を合体させて
  2. usortで自前の比較関数cmp_by_dateを使ってソートしてます。
<?php
$a = array(
        array('aaa', '00a', '2007-01-31 12:00:00'),
        array('bbb', '00b', '2007-02-31 12:00:00')
);
$b = array(
        array('eee', '00e', '2007-05-31 12:00:00'),
        array('fff', '00f', '2007-06-31 12:00:00')
);
$c = array(
        array('hhh', '00h', '2007-03-31 12:00:00'),
        array('iii', '00i', '2007-04-31 12:00:00')
);

$d = array_merge($a, $b, $c);
usort($d, 'cmp_by_date');
print_r($d);

function cmp_by_date($v1, $v2) {
        return $v1[2] < $v2[2];
}
?>

↑の実行結果は↓

Array
(
    [0] => Array
        (
            [0] => fff
            [1] => 00f
            [2] => 2007-06-31 12:00:00
        )
    [1] => Array
        (
            [0] => eee
            [1] => 00e
            [2] => 2007-05-31 12:00:00
        )
    [2] => Array
        (
            [0] => iii
            [1] => 00i
            [2] => 2007-04-31 12:00:00
        )
    [3] => Array
        (
            [0] => hhh
            [1] => 00h
            [2] => 2007-03-31 12:00:00
        )
    [4] => Array
        (
            [0] => bbb
            [1] => 00b
            [2] => 2007-02-31 12:00:00
        )
    [5] => Array
        (
            [0] => aaa
            [1] => 00a
            [2] => 2007-01-31 12:00:00
        )
)
id:seadwell

ご回答ありがとうございますm(_ _)m

いや~、全くこんなカンジです^^/

ズバリ答えを書いていただいていますが、私なりにいろいろ実験して、結果報告いたします。

ありがとうございました。

2007/10/26 20:31:09
  • id:seadwell
    GEN111さん、y-kawazさんありがとうございました。
    動作を確認しました。

    しかし、y-kawazさんの回答に質問があります。
    function cmp_by_date($v1, $v2)の$v1と$v2は何処からやってきたんですか?
    よろしかったら教えてくださいm(_ _)m
    自分なりにusortとfunctionを調べましたが解りませんでした。
    データを増やしてもちゃんとソートされるので不思議です。
  • id:GEN111
    「usort」はソートに使う比較関数を自分で定義できるものです。
    create_function で usort の中に埋め込んだのが私のやり方で、外に出したのが y-kawaz さんのやり方です。
    usort に限らずソート関数は配列の要素の二つずつの大小を調べて並べ換えしていきます。
    比較関数は usort から二つの引数を受けとり、二つを比較した結果を返します。
    その二つにとりあえず名前をつけて受けとるのが私の '$a, $b'、y-kawaz さんの ($v1, $v2) です。
    引数が二つなら名前はなんでもかまいません (関数内で使う名前と合っていれば)。
    マニュアルでは
    >>
    比較関数は、最初の引数が 2 番目の引数より小さいか、等しいか、大きい場合に、 それぞれゼロ未満、ゼロに等しい、ゼロより大きい整数を返す 必要があります。
    <<
    とあるので比較関数は三種類の価を返す方が行儀は良いと思います。


    ちなみに、Perl では比較関数が使うのは $a と $b という名前に決まっています。
  • id:seadwell
    GEN111さん、ご丁寧にありがとうございますm(_ _)m

    > とあるので比較関数は三種類の価を返す方が行儀は良いと思います。
    ナルホド・・・。
    勉強になります。
    非常に、解りやすいです。

    ありがとうございました ^^/

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

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

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

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