データベーステーブルを模倣する配列があるとします。各配列要素は行を表し、各行内にはフィールド名と値を含む別の配列があります。
Array
(
[0] => Array
(
[name] => 'Sony TV'
[price] => 600.00
)
[1] => Array
(
[name] => 'LG TV'
[price] => 350.00
)
[2] => Array
(
[name] => 'Samsung TV'
[price] => 425.00
)
}
私がやりたいのは、行(外部配列要素)を価格で並べ替えることです。以下は私が達成したいことの例です:
Array
(
[0] => Array
(
[name] => 'LG TV'
[price] => 350.00
)
[1] => Array
(
[name] => 'Samsung TV'
[price] => 425.00
)
[2] => Array
(
[name] => 'Sony TV'
[price] => 600.00
)
}
ご覧のとおり、外側の配列のキーを保持する必要はありません。
sort を使用する必要があります。これは、ユーザー定義関数を介して配列をソートする関数です。何かのようなもの:
function cmp($a, $b)
{
if ($a["price"] == $b["price"]) {
return 0;
}
return ($a["price"] < $b["price"]) ? -1 : 1;
}
usort($yourArray,"cmp")
ワンライナーです
array_multisort( array_column($yourArray, "price"), SORT_ASC, $yourArray );
ここでも見つけることができます: http://php.net/manual/en/function.array-multisort.php
そのマニュアルページで「array_column」を検索してください。
usort()
を使用できます:
_function sort($a, $b) {
if ($a['price'] == $b['price']) return 0;
return ($a['price'] > $b['price']) ? 1 : -1;
}
usort($array, 'sort');
_
次のようなクラスを作成してコードを再利用すると、さらに効果的です。
_class FieldSorter {
public $field;
function __construct($field) {
$this->field = $field;
}
function cmp($a, $b) {
if ($a[$this->field] == $b[$this->field]) return 0;
return ($a[$this->field] > $b[$this->field]) ? 1 : -1;
}
}
$sorter = new FieldSorter('price');
usort($array, array($sorter, "cmp"));
_
このようにして、他のフィールドで簡単に並べ替えることができます。
また、外側の配列のキーを保持する必要はないとおっしゃいましたが、usort
の代わりに uasort()
を使用することで簡単にこれを実現できます。
これは基本的に受け入れられた回答と同じですが、これにusort
を使用するのがより便利になるように、いくつかの新機能がPHPに長年にわたって追加されています。
$column = 'price';
usort($table, function($a, $b) use ($column) {
return $a[$column] <=> $b[$column];
});
比較コールバックに 匿名関数 を使用できるようになりました(PHP 5.3)以降、PHP 7で- 結合された比較演算子 (<=>
)、これにより比較ロジックを減らすことができます
if ($a['price'] == $b['price']) return 0;
return ($a['price'] > $b['price']) ? 1 : -1;
単一の式に
return $a[$column] <=> $b[$column];
この質問は少し古いですが、将来のためにここに答えを残します。
php.net-Multisort 関数から、以下のコードを使用できます。
$data= [['volume' => 67, 'edition' => 2],['volume' => 85, 'edition' => 6],...];
foreach ($data as $key => $row) {
$volume[$key] = $row['volume'];
$edition[$key] = $row['edition'];
}
array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
上記は、ソート列を手動で変更するデータの静的ソート用です。
より動的で堅牢な例については、以下を検討してください。
以下のデータがあると仮定します。
$data = [[1, 'Amanda', 'Wright', '[email protected]', 'Female', '135.114.57.89', 31237],
[2, 'Theresa', 'Larson', '[email protected]', 'Female', '207.108.96.210', 91011],
[3, 'Walter', 'Kennedy', '[email protected]', 'Male', '199.147.223.56', 50114],
[4, 'Andrea', 'Richards', '[email protected]', 'Female', '230.195.124.95', 76489],
[5, 'Carol', 'Jones', '[email protected]', 'Female', '250.197.111.90', 56501],
[6, 'Alice', 'Freeman', '[email protected]', 'Female', '52.195.252.131', 77170],
[7, 'Gerald', 'Fisher', '[email protected]', 'Male', '81.2.22.62', 75625],....]
上記の配列データをそのまま並べ替える必要がある場合は、構文を使用して配列に並べ替え順序を設定できます。
$qTable[$index]=$sort_order;
E.g. $qTable=[1=>'asc',4=>'desc',3=>'asc'];
これは、列1 ASC、列4 DESC、列3ASCの順に並べ替えることを意味します。次に、以下の関数を使用して、多次元データベースデータを並べ替えることができます。
function sortMulti($data, $orders)
{
$args = [];
foreach ($data as $key => $row) {
foreach ($orders as $index => $order) {
if (!isset($row[$index])) continue; //Ignore if column does'nt exist
$args[$index]['d'][$key] = $row[$index]; //Get all values within the column
$args[$index]['o'] = 'desc' == strtolower($order) ? SORT_DESC : SORT_ASC; //Get the Sort order 'ASC' is the default
}
}
$p = [];
//Below we need to organize our entries as arguments for array_multisort
foreach ($args as $arg) {
$p[] = $arg['d'];
$p[] = $arg['o'];
//Below we need to check if column contains only numeric or not.
//If all values are numeric, then we use numeric sort flag, otherwise NATURAL
//Manipulate for more conditions supported
$p[] = count($arg['d']) == count(array_filter($arg['d'], 'is_numeric')) ? SORT_NUMERIC : SORT_NATURAL;
}
$p[] = &$data; //Pass by reference
call_user_func_array('array_multisort', $p); //Call Php's own multisort with parameters in required order.
return $data; //Our final array sorted.
}
次に、以下のように使用できます。
$data=[[...],[...],...];
$order=[1=>'asc',4=>'desc',3=>'asc'];
$sorted=sortMulti($data,$order);
キー値配列データの場合E.g. $data=[['c1'=>1212,'c2'=>'mynames'],...];
順序を$order=['c1'=>'desc','c10'=>'asc'];
として使用します
上記を1000レコードの配列でテストしました。それが誰かを助けることを願っています。
sortの代わりに、並べ替える配列にインデックスを付け、並べ替えるデータによってインデックスを付ける配列を作成することもできます。
以下のスニペットでは、$ customAttributesは、nameで並べ替えたいオブジェクトの配列です。最初に$ sortが作成され、nameでインデックスが付けられ、対応する$ customAttributesの配列インデックスが含まれます。 =要素。
$sort = [];
foreach( $customAttributes as $c => $ca )
{
$sort[$ca->name] = $c;
}
ksortは、配列をキーでソートするために使用されます。
ksort( $sort );
$ sort配列が並べ替えられたら、それを繰り返し処理して$ ordered配列を作成します。
$ordered = [];
foreach( $sort as $s )
{
$ordered[] = $customAttributes[$s];
}
コールバックを使用するよりも関数呼び出しが少ないので、このソリューションが好きです。
以下のような関数を自分で作成できます
プライベート関数orderArrayBycolumn($ array、$ column){
$newArray = [];
foreach ($array as $key => $value) {
$newArray[$value[$column]] = $value;
}
$array = [];
ksort($newArray);
foreach ($newArray as $key => $value) {
$array[] = $value;
}
return $array;
}
コールバックでusort関数を使用できます