[英]How to Sort a Multi-dimensional Array by Value
我如何根據“order”鍵的值對這個數組進行排序?
盡管這些值當前是連續的,但它們並不總是如此。
Array
(
[0] => Array
(
[hashtag] => a7e87329b5eab8578f4f1098a152d6f4
[title] => Flower
[order] => 3
)
[1] => Array
(
[hashtag] => b24ce0cd392a5b0b8dedc66c25213594
[title] => Free
[order] => 2
)
[2] => Array
(
[hashtag] => e7d31fc0602fb2ede144d18cdffd816b
[title] => Ready
[order] => 1
)
)
嘗試一個usort 。 如果您仍在使用 PHP 5.2 或更早版本,則必須先定義排序函數:
function sortByOrder($a, $b) {
return $a['order'] - $b['order'];
}
usort($myArray, 'sortByOrder');
從 PHP 5.3 開始,您可以使用匿名函數:
usort($myArray, function($a, $b) {
return $a['order'] - $b['order'];
});
最后,在 PHP 7 中,您可以使用spaceship 運算符:
usort($myArray, function($a, $b) {
return $a['order'] <=> $b['order'];
});
要將其擴展到多維排序,請在第一個排序元素為零時引用第二個/第三個排序元素 - 最好在下面解釋。 您還可以使用它對子元素進行排序。
usort($myArray, function($a, $b) {
$retval = $a['order'] <=> $b['order'];
if ($retval == 0) {
$retval = $a['suborder'] <=> $b['suborder'];
if ($retval == 0) {
$retval = $a['details']['subsuborder'] <=> $b['details']['subsuborder'];
}
}
return $retval;
});
如果您需要保留鍵關聯,請使用uasort()
- 請參閱手冊中數組排序功能的比較。
function aasort (&$array, $key) {
$sorter = array();
$ret = array();
reset($array);
foreach ($array as $ii => $va) {
$sorter[$ii] = $va[$key];
}
asort($sorter);
foreach ($sorter as $ii => $va) {
$ret[$ii] = $array[$ii];
}
$array = $ret;
}
aasort($your_array, "order");
我使用這個功能:
function array_sort_by_column(&$arr, $col, $dir = SORT_ASC) {
$sort_col = array();
foreach ($arr as $key => $row) {
$sort_col[$key] = $row[$col];
}
array_multisort($sort_col, $dir, $arr);
}
array_sort_by_column($array, 'order');
編輯此答案至少已有十年歷史,現在可能有更好的解決方案,但我正在根據幾條評論的要求添加一些額外信息。
它有效是因為array_multisort()
可以對多個數組進行排序。 示例輸入:
Array
(
[0] => Array
(
[hashtag] => a7e87329b5eab8578f4f1098a152d6f4
[title] => Flower
[order] => 3
)
[1] => Array
(
[hashtag] => b24ce0cd392a5b0b8dedc66c25213594
[title] => Free
[order] => 2
)
首先創建$sort_col
,它是一個二維數組,其中的值是我們想要排序的,並且鍵匹配輸入數組。 例如對於這個輸入,選擇鍵$sort_col
"order"
我們得到:
Array
(
[0] => 3,
[1] => 2
)
array_multisort()
然后對該數組進行排序(導致鍵順序為1, 0
),但這只是二維數組。 所以原始輸入數組也作為$rest
參數傳遞。 當鍵匹配時,它將被排序,所以它的鍵也按相同的順序,給出所需的結果。
筆記:
array_multisort()
可以像這樣對多個附加數組進行排序,而不僅僅是一個為了實現這一點,我們可以使用“array_multisort”方法“對多維或多維數組進行排序”。 它的方法參數是
'sort flags' 默認是 SORT_REGULAR,它被省略。
$new = [
[
'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4',
'title' => 'Flower',
'order' => 3,
],
[
'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594',
'title' => 'Free',
'order' => 2,
],
[
'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b',
'title' => 'Ready',
'order' => 1,
],
];
$keys = array_column($new, 'order');
array_multisort($keys, SORT_ASC, $new);
var_dump($new);
結果:
Array
(
[0] => Array
(
[hashtag] => e7d31fc0602fb2ede144d18cdffd816b
[title] => Ready
[order] => 1
)
[1] => Array
(
[hashtag] => b24ce0cd392a5b0b8dedc66c25213594
[title] => Free
[order] => 2
)
[2] => Array
(
[hashtag] => a7e87329b5eab8578f4f1098a152d6f4
[title] => Flower
[order] => 3
)
)
我通常使用usort ,並傳遞我自己的比較函數。 在這種情況下,它非常簡單:
function compareOrder($a, $b)
{
return $a['order'] - $b['order'];
}
usort($array, 'compareOrder');
在 PHP 7 中使用 spaceship 運算符:
usort($array, function($a, $b) {
return $a['order'] <=> $b['order'];
});
要按“title”鍵的值對數組進行排序,請使用:
uasort($myArray, function($a, $b) {
return strcmp($a['title'], $b['title']);
});
strcmp比較字符串。
uasort()維護定義的數組鍵。
使用array_multisort()
, array_map()
array_multisort(array_map(function($element) {
return $element['order'];
}, $array), SORT_ASC, $array);
print_r($array);
$sort = array();
$array_lowercase = array_map('strtolower', $array_to_be_sorted);
array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $alphabetically_ordered_array);
這會處理大寫和小寫字母。
正如接受的答案所述,您可以使用:
usort($myArray, function($a, $b) {
return $a['order'] <=> $b['order'];
});
如果您需要按多列排序,那么您將執行以下操作:
usort($myArray, function($a, $b) {
return [$a['column1'],$a['column2']] <=> [$b['column1'],$b['column2']];
});
這可以擴展到數據中的任意數量的列。 這取決於您可以直接比較 PHP 中的 arrays 的事實。 在上面的示例中,數組將首先按column1
排序,然后按column2
排序。 但是您可以按任何順序按列排序,例如:
usort($myArray, function($a, $b) {
return [$a['column2'],$a['column1']] <=> [$b['column2'],$b['column1']];
});
如果您需要對一列進行升序和另一列降序排序,則將降序列交換到運算符<=>
的另一側:
usort($myArray, function($a, $b) {
return [$a['column1'],$b['column2']] <=> [$b['column1'],$a['column2']];
});
最靈活的方法是使用這種方法:
Arr::sortByKeys(array $array, $keys, bool $assoc = true): array
原因如下:
您可以按任何鍵排序(也可以嵌套,如'key1.key2.key3'
或['k1', 'k2', 'k3']
)
它適用於關聯數組和非關聯數組( $assoc
標志)
它不使用引用 - 它返回一個新的排序數組
在你的情況下,它會很簡單:
$sortedArray = Arr::sortByKeys($array, 'order');
這個方法是這個庫的一部分。
如果有人需要根據鍵進行排序,最好使用以下方法:
usort($array, build_sorter('order'));
function build_sorter($key) {
return function ($a, $b) use ($key) {
return strnatcmp($a[$key], $b[$key]);
};
}
就這樣做,適用於7.4及更高版本
uasort($yourArray,fn($prev,$now)=>$prev['order']<=>$now['order']);
漂亮的印刷品
echo '<pre>';
print_r($yourArray);
此解決方案適用於 usort(),具有易於記憶的多維排序符號。 使用宇宙飛船運算符 <=>,可從 PHP 7 獲得。
usort($in,function($a,$b){
return $a['first'] <=> $b['first'] //first asc
?: $a['second'] <=> $b['second'] //second asc
?: $b['third'] <=> $a['third'] //third desc (a b swapped!)
//etc
;
});
例子:
$in = [
['firstname' => 'Anton', 'surname' => 'Gruber', 'birthdate' => '03.08.1967', 'rank' => 3],
['firstname' => 'Anna', 'surname' => 'Egger', 'birthdate' => '04.01.1960', 'rank' => 1],
['firstname' => 'Paul', 'surname' => 'Mueller', 'birthdate' => '15.10.1971', 'rank' => 2],
['firstname' => 'Marie', 'surname' => 'Schmidt ', 'birthdate' => '24.12.1963', 'rank' => 2],
['firstname' => 'Emma', 'surname' => 'Mueller', 'birthdate' => '23.11.1969', 'rank' => 2],
];
第一個任務:按職級升序,姓氏升序
usort($in,function($a,$b){
return $a['rank'] <=> $b['rank'] //first asc
?: $a['surname'] <=> $b['surname'] //second asc
;
});
第二個任務:按等級降序、姓氏升序、姓氏升序排序
usort($in,function($a,$b){
return $b['rank'] <=> $a['rank'] //first desc
?: $a['surname'] <=> $b['surname'] //second asc
?: $a['firstname'] <=> $b['firstname'] //third asc
;
});
第三個任務:Order By rank desc,生日升序
不能在此表示法中對日期進行排序。 它是用strtotime 轉換的。
usort($in,function($a,$b){
return $b['rank'] <=> $a['rank'] //first desc
?: strtotime($a['birthdate']) <=> strtotime($b['birthdate']) //second asc
;
});
您可以使用帶有回調函數的usort
和用戶定義的排序函數:
usort($new, fn($a, $b) => $a['order'] - $b['order']);
技巧:您可以使用a > b
或a - b
或a <=> b
進行升序排序。 對於降序,只是a
和b
的交換位置。
讓我們面對現實吧:PHP沒有一個簡單外的存儲箱功能,妥善處理每一個數組排序情況。
這個例程很直觀,這意味着更快的調試和維護:
// Automatic population of the array
$tempArray = array();
$annotations = array();
// ... some code
// SQL $sql retrieves result array $result
// $row[0] is the ID, but is populated out of order (comes from
// multiple selects populating various dimensions for the same DATE
// for example
while($row = mysql_fetch_array($result)) {
$needle = $row[0];
arrayIndexes($needle); // Create a parallel array with IDs only
$annotations[$needle]['someDimension'] = $row[1]; // Whatever
}
asort($tempArray);
foreach ($tempArray as $arrayKey) {
$dataInOrder = $annotations[$arrayKey]['someDimension'];
// .... more code
}
function arrayIndexes ($needle) {
global $tempArray;
if (!in_array($needle, $tempArray)) {
array_push($tempArray, $needle);
}
}
我發現這很有幫助:
$columns = array_column($data, "order");
array_multisort($columns, SORT_ASC, $data);
example with class:
class user
{
private $key;
public function __construct(string $key)
{
$this->key = $key;
}
public function __invoke($a, $b)
{
return $a[$this->key] <=> $b[$this->key];
}
}
$user = [
['id' => 1, 'name' => 'Oliver', 'id_card' => 4444],
['id' => 3, 'name' => 'Jack', 'id_card' => 5555],
['id' => 2, 'name' => 'Harry', 'id_card' => 6666]
];
// sort user by id
usort($user, new user('id'));
var_dump($user);
另一個基於相同邏輯的 function:
function array_multisort(&$a, array $column_names) {
usort($a, function($a, $b) use($column_names) {
foreach ($column_names as $column_name => $order) {
$result = ($a[$column_name] <=> $b[$column_name]) * ($order === SORT_DESC ? -1 : 1);
if ($result) return $result;
}
return 0;
});
}
$data[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);
var_dump($data);
array_multisort($data, ['volume' => SORT_ASC, 'edition' => SORT_DESC]);
var_dump($data);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.