配列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
)
)
地道にやってもいいと思いますが、スマートに書くとしたら、これでどうでしょう?
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");
こんなのでどうでしょうか?
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); }
ありがとうございます。
最初の方の回答ですが
<?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));
二つめのほうはもっといいやりかたがあるかもしれませんが思い付きませんでした。
ありがとうございます。
ありがとうございます。