PHPで以下の配列があり

配列A
Array
(
[0] => Array
(
[TEST1] => 2222
[TEST2] => OK
[TEST3] => 8888
)
[1] => Array
(
[TEST1] => 33333
[TEST2] => NG
[TEST3] => 9999
)
[2] => Array
(
[TEST1] => 44444
[TEST2] => OK
[TEST3] => 77777
)
)
をまずTEST3の項目で昇順にソートして
TEST2の項目がOK、NG、OK、NGみたいに
なるようにするにはどうしたらいいですか?
もしもOK、OK、OKなどに並ぶようなら
最初にOKが格納されたら、次にNGが来るまでの
配列の値は削除するようにしたいのですが
どうしたらいいのでしょうか?
結果:
Array
(
[0] => Array
(
[TEST1] => 4444
[TEST2] => OK
[TEST3] => 7777
)
[1] => Array
(
[TEST1] => 33333
[TEST2] => NG
[TEST3] => 9999
)
)

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

回答3件)

id:t_shiono No.1

回答回数256ベストアンサー獲得回数22

ポイント27pt

地道にやってもいいと思いますが、スマートに書くとしたら、これでどうでしょう?

function cmp($lhs, $rhs) {
  $lv = $lhs["TEST3"];
  $rv = $rhs["TEST3"];
  if ($lv < $rv) {
    return -1;
  } else if ($lv > $rv) {
    return 1;
  } else {
    return 0;
  }
}

$expect = 0;
function check($item) {
  global $expect;

  $list = array("OK", "NG");
  if (strcmp($item["TEST2"], $list[$expect]) == 0) {
    $expect = ($expect + 1) % 2;
    return true;
  } else {
    return false;
  }
}



$a = array(
        array("TEST1" => 2222, "TEST2" => "OK", "TEST3" => 8888),
        array("TEST1" => 3333, "TEST2" => "NG", "TEST3" => 9999),
        array("TEST1" => 4444, "TEST2" => "OK", "TEST3" => 7777));

usort($a, "cmp");
$result = array_filter($a, "check");

id:hopefully

ありがとうございます。

2007/06/12 11:06:58
id:tezcello No.2

回答回数460ベストアンサー獲得回数69

ポイント27pt

こんなのでどうでしょうか?

TEST3, TEST1, TEST2 の順になる様に各項目を連結し、配列を作ります。

これをソートすると、TEST3 の項目でソートした事になります。

この配列の全要素において、最後の3文字が '_OK' であるかをチェックします。(2文字だけでも可)

既に '_OK' の直後であれば、次の値を調べます。

そうでない場合は結果配列に格納します。

  連結した時に、各項目の間に挟んだ文字 '_' で分割し、

  それぞれを項目名をキーとした連想配列として格納する。

$array_A = array(
   array('TEST1'=>'2222', 'TEST2'=>'OK', 'TEST3'=>'8888')
  ,array('TEST1'=>'33333', 'TEST2'=>'NG', 'TEST3'=>'9999')
  ,array('TEST1'=>'44444', 'TEST2'=>'OK', 'TEST3'=>'7777')  // 質問文での元配列は '77777' ですが、結果の配列に合わせました
  );

foreach($array_A as $a){
  $array_B[] = $a['TEST3'].'_'.$a['TEST1'].'_'.$a['TEST2'];
}
sort($array_B);

$f = FALSE;
foreach($array_B as $a){
  if (ereg('.*_OK', $a)){
    if ($f)	continue; else $f = TRUE;
  }else $f= FALSE;
  list($TEST3, $TEST1, $TEST2) = explode('_', $a);
  $res[] = array('TEST1'=>$TEST1, 'TEST2'=>$TEST2, 'TEST3'=>$TEST3);
}
id:hopefully

ありがとうございます。

2007/06/12 11:06:55
id:rudeboyjet No.3

回答回数11ベストアンサー獲得回数1

ポイント26pt

最初の方の回答ですが

<?php
$ary = array(0 => array('TEST1' => 2222,
                        'TEST2' => 'OK',
                        'TEST3' => 8888),
             1 => array('TEST1' => 333333,
                        'TEST2' => 'NG',
                        'TEST3' => 9999),
             2 => array('TEST1' => 44444,
                        'TEST2' => 'OK',
                        'TEST3' => 777777));


function cmp($a, $b)
{
  if($a['TEST3'] == $b['TEST3']){
    return 0;
  }
  return ($a['TEST3'] < $b['TEST3']) ? -1 : 1;
}

usort($ary, 'cmp');
var_dump($ary);

二つめですが

<?php
$ary = array(0 => array('TEST1' => 2222,
                        'TEST2' => 'OK',
                        'TEST3' => 8888),
             1 => array('TEST1' => 333333,
                        'TEST2' => 'NG',
                        'TEST3' => 9999),
             2 => array('TEST1' => 44444,
                        'TEST2' => 'OK',
                        'TEST3' => 777777),
             3 => array('TEST1' => 44444,
                        'TEST2' => 'OK',
                        'TEST3' => 777777),
             4 => array('TEST1' => 2434,
                        'TEST2' => 'NG',
                        'TEST3' => 777777));

function compress_by_test2($ary, $product=NULL)
{
  if($ary == NULL){
    return $product;
  }

  if($product == NULL){
    $product = array();
    array_push($product, array_shift($ary));
  }
  $target = array_shift($ary);
  if($product[sizeof($product) - 1]['TEST2'] != $target['TEST2']){
    array_push($product, $target);
  }
  return compress_by_test2($ary, $product);
}

var_dump(compress_by_test2($ary));

二つめのほうはもっといいやりかたがあるかもしれませんが思い付きませんでした。

id:hopefully

ありがとうございます。

2007/06/12 11:06:52
  • id:t_shiono
    さきほどの例ですが、array_filterの実装に依存する部分がありました。
    というのは、フィルタをかける際に先頭の要素からフィルタのチェックを行わないとうまく動きません。手元の環境では大丈夫でしたし、その順番で行わないための優位な点もないので、まず大丈夫だとは思うのですが、マニュアルには、先頭の要素からチェックを行うことは記載されていなかったので、仕様としては、未定なのかと思います。

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

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

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

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