まずやりたいこと(仕様)
・並べ替えたい配列(ポケモンデータ)がある
・並び替えるルールは 3段階で決める
・まずは bunrui_id が小さいものを先にする
・同じ bunrui_id の中では、job_id の中で一番小さい数字を比べる
・job_id は「1,3」とか「5,2」みたいにカンマ区切りで複数入っているので、その中で一番小さい数字を探す
・bunrui_id も job_id も同じなら、id が小さい順にする
・job_idが0または未入力なら最後尾に
・job_idがマイナスの数字があれば評価しない
コード1
// job_idから最小の正の値を取る(負数や0は無視、全部無効なら最後尾用にPHP_INT_MAX)
function minJobId($job_id) {
if (empty($job_id)) return PHP_INT_MAX;
$ids = array_map('intval', explode(',', $job_id));
$ids = array_filter($ids, function ($v) {
return $v > 0; // 正の数だけ残す
});
return $ids ? min($ids) : PHP_INT_MAX;
}
// ソート処理
usort($query_data, function ($a, $b) {
return $a['bunrui_id'] <=> $b['bunrui_id'] // 第1キー
?: minJobId($a['job_id']) <=> minJobId($b['job_id']) // 第2キー
?: $a['id'] <=> $b['id']; // 第3キー
});
コード2
function minJobId($job_id) {
if (empty($job_id)) return PHP_INT_MAX;
return min(array_map('intval', explode(',', $job_id)));
}
// ソート処理
usort($query_data, function ($a, $b) {
return $a['bunrui_id'] <=> $b['bunrui_id'] // 第1キー
?: minJobId($a['job_id']) <=> minJobId($b['job_id']) // 第2キー
?: $a['id'] <=> $b['id']; // 第3キー
});
コード3
<?php
$query_data = [
['id'=> 1,'name'=>'イワーク','job_id'=>'1,3','bunrui_id' => 2,'waza'=>'岩雪崩'],
['id'=> 2,'name'=>'ピカチュウ','job_id'=>'5,2','bunrui_id' => 2,'waza'=>'電気ショック'],
['id'=> 3,'name'=>'ヤドラン','job_id'=>'2,7','bunrui_id' => 4,'waza'=>'水鉄砲'],
['id'=> 4,'name'=>'ピジョン','job_id'=>'9,3','bunrui_id' => 1,'waza'=>'風起こし'],
['id'=> 5,'name'=>'カイリュー','job_id'=>'9,4','bunrui_id' => 1,'waza'=>'龍の怒り'],
['id'=> 6,'name'=>'スピアー','job_id'=>'2','bunrui_id' => 4,'waza'=>'ダブルニードル'],
];
usort($query_data, function($a, $b) {
// --- 第1キー bunrui_id ---
if ($a['bunrui_id'] !== $b['bunrui_id']) {
return $a['bunrui_id'] - $b['bunrui_id'];
}
// --- 第2キー job_id(最小の正の数値を優先、負数は無視) ---
$aJobMin = null;
$bJobMin = null;
if (!empty($a['job_id'])) {
$aJobs = array_map('intval', explode(',', $a['job_id']));
$aJobs = array_filter($aJobs, function($v) { return $v >= 0; }); // 負数を無視
if (!empty($aJobs)) {
$aJobMin = min($aJobs);
}
}
if (!empty($b['job_id'])) {
$bJobs = array_map('intval', explode(',', $b['job_id']));
$bJobs = array_filter($bJobs, function($v) { return $v >= 0; }); // 負数を無視
if (!empty($bJobs)) {
$bJobMin = min($bJobs);
}
}
// どちらかが null の場合は null を最後尾にする
if ($aJobMin === null && $bJobMin === null) {
// → 第3キー A.id で昇順
return $a['id'] - $b['id'];
} elseif ($aJobMin === null) {
return 1; // aだけnull → bが先
} elseif ($bJobMin === null) {
return -1; // bだけnull → aが先
}
// 両方数値がある場合 → 昇順比較
if ($aJobMin !== $bJobMin) {
return $aJobMin - $bJobMin;
}
// --- 第3キー A.id ---
return $a['id'] - $b['id'];
});
echo('<pre>');var_dump($query_data);echo('</pre>');
結果
<pre>array(6) {
[0]=>
array(5) {
["id"]=>
int(4)
["name"]=>
string(12) "ピジョン"
["job_id"]=>
string(3) "9,3"
["bunrui_id"]=>
int(1)
["waza"]=>
string(12) "風起こし"
}
[1]=>
array(5) {
["id"]=>
int(5)
["name"]=>
string(15) "カイリュー"
["job_id"]=>
string(3) "9,4"
["bunrui_id"]=>
int(1)
["waza"]=>
string(12) "龍の怒り"
}
[2]=>
array(5) {
["id"]=>
int(1)
["name"]=>
string(12) "イワーク"
["job_id"]=>
string(3) "1,3"
["bunrui_id"]=>
int(2)
["waza"]=>
string(9) "岩雪崩"
}
[3]=>
array(5) {
["id"]=>
int(2)
["name"]=>
string(15) "ピカチュウ"
["job_id"]=>
string(3) "5,2"
["bunrui_id"]=>
int(2)
["waza"]=>
string(18) "電気ショック"
}
[4]=>
array(5) {
["id"]=>
int(3)
["name"]=>
string(12) "ヤドラン"
["job_id"]=>
string(3) "2,7"
["bunrui_id"]=>
int(4)
["waza"]=>
string(9) "水鉄砲"
}
[5]=>
array(5) {
["id"]=>
int(6)
["name"]=>
string(12) "スピアー"
["job_id"]=>
string(1) "2"
["bunrui_id"]=>
int(4)
["waza"]=>
string(21) "ダブルニードル"
}
}
</pre>