<?php
$values = [
[
'id' => '2',
'category_id' => 'A',
], [
'id' => '30',
'category_id' => 'A',
], [
'id' => '12',
'category_id' => 'B',
], [
'id' => '8',
'category_id' => 'B',
], [
'id' => '10',
'category_id' => 'C',
], [
'id' => '329',
'category_id' => 'D',
], [
'id' => '89',
'category_id' => 'E',
], [
'id' => '79',
'category_id' => 'E',
], [
'id' => '58',
'category_id' => 'A',
], [
'id' => '219',
'category_id' => 'B',
], [
'id' => '44',
'category_id' => 'B',
], [
'id' => '3219',
'category_id' => 'B',
], [
'id' => '231',
'category_id' => 'B',
], [
'id' => '43210',
'category_id' => 'F',
]
];
// 一次元配列にする
$categoryIds = array_column($values, 'category_id');
// 処理済みの category_id を格納する変数
$sorted = [];
// 残っている category_id が一種類のみかどうかを判定する変数
$hasOneSubject = false;
$sorting = function ($categoryIds) use (&$sorting, &$sorted, &$hasOneCategory) {
// 重複を削除した category_id
$uniqueCategory = array_unique($categoryIds);
// 使用済みの category_id を格納しておく変数
$used = [];
foreach ($categoryIds as $index => $id) {
// 処理済みの配列から一番最後を取得
$lastKey = array_key_last($sorted);
// 残りの category_id が一種類しかない場合を除き、直近の配列が同じ場合はskip。
if (isset($sorted[$lastKey]) && $sorted[$lastKey] === $id && !$hasOneCategory) {
continue;
}
// category_id を全種類使い切った場合は使用済みをリセットする
if (count($uniqueCategory) === count(array_unique($used))) {
$used = [];
}
// 既に同一の category_id を処理済みの場合はskip
if (in_array($id, $used)) {
continue;
}
$sorted[$index] = $id;
$used[] = $id;
}
// 残りの配列
$diff = array_diff_assoc($categoryIds, $sorted);
// 残りの配列が一種類かどうか
$hasOneCategory = count(array_unique($diff)) === 1;
// 残っている配列がある場合は再帰処理を実施
if (count($diff) > 0) {
return $sorting($diff);
}
return $sorted;
};
$sortedValues = [];
// 二次元配列次元配列として入れ直す
foreach ($sorting($categoryIds) as $key => $value) {
$sortedValues[$key] = $values[$key];
}
var_dump($sortedValues);
- Output for 7.3.13 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.31, 8.2.0 - 8.2.27, 8.3.0 - 8.3.4, 8.3.6 - 8.3.15, 8.4.1 - 8.4.2
- array(14) {
[0]=>
array(2) {
["id"]=>
string(1) "2"
["category_id"]=>
string(1) "A"
}
[2]=>
array(2) {
["id"]=>
string(2) "12"
["category_id"]=>
string(1) "B"
}
[4]=>
array(2) {
["id"]=>
string(2) "10"
["category_id"]=>
string(1) "C"
}
[5]=>
array(2) {
["id"]=>
string(3) "329"
["category_id"]=>
string(1) "D"
}
[6]=>
array(2) {
["id"]=>
string(2) "89"
["category_id"]=>
string(1) "E"
}
[13]=>
array(2) {
["id"]=>
string(5) "43210"
["category_id"]=>
string(1) "F"
}
[1]=>
array(2) {
["id"]=>
string(2) "30"
["category_id"]=>
string(1) "A"
}
[3]=>
array(2) {
["id"]=>
string(1) "8"
["category_id"]=>
string(1) "B"
}
[7]=>
array(2) {
["id"]=>
string(2) "79"
["category_id"]=>
string(1) "E"
}
[8]=>
array(2) {
["id"]=>
string(2) "58"
["category_id"]=>
string(1) "A"
}
[9]=>
array(2) {
["id"]=>
string(3) "219"
["category_id"]=>
string(1) "B"
}
[10]=>
array(2) {
["id"]=>
string(2) "44"
["category_id"]=>
string(1) "B"
}
[11]=>
array(2) {
["id"]=>
string(4) "3219"
["category_id"]=>
string(1) "B"
}
[12]=>
array(2) {
["id"]=>
string(3) "231"
["category_id"]=>
string(1) "B"
}
}
- Output for 8.3.5
- Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
array(14) {
[0]=>
array(2) {
["id"]=>
string(1) "2"
["category_id"]=>
string(1) "A"
}
[2]=>
array(2) {
["id"]=>
string(2) "12"
["category_id"]=>
string(1) "B"
}
[4]=>
array(2) {
["id"]=>
string(2) "10"
["category_id"]=>
string(1) "C"
}
[5]=>
array(2) {
["id"]=>
string(3) "329"
["category_id"]=>
string(1) "D"
}
[6]=>
array(2) {
["id"]=>
string(2) "89"
["category_id"]=>
string(1) "E"
}
[13]=>
array(2) {
["id"]=>
string(5) "43210"
["category_id"]=>
string(1) "F"
}
[1]=>
array(2) {
["id"]=>
string(2) "30"
["category_id"]=>
string(1) "A"
}
[3]=>
array(2) {
["id"]=>
string(1) "8"
["category_id"]=>
string(1) "B"
}
[7]=>
array(2) {
["id"]=>
string(2) "79"
["category_id"]=>
string(1) "E"
}
[8]=>
array(2) {
["id"]=>
string(2) "58"
["category_id"]=>
string(1) "A"
}
[9]=>
array(2) {
["id"]=>
string(3) "219"
["category_id"]=>
string(1) "B"
}
[10]=>
array(2) {
["id"]=>
string(2) "44"
["category_id"]=>
string(1) "B"
}
[11]=>
array(2) {
["id"]=>
string(4) "3219"
["category_id"]=>
string(1) "B"
}
[12]=>
array(2) {
["id"]=>
string(3) "231"
["category_id"]=>
string(1) "B"
}
}
preferences:
124.48 ms | 413 KiB | 5 Q