[英]Undefined offset when using bubble sort on associative array
我有這個函數可以根據鍵輸入對關聯數組進行冒泡排序,並可以選擇按降序或升序排序:
function bubbleSort($input, $key, $order){
while (true){
$end = false;
$swapped = false;
$idx = 0;
do {
$x = $input[$idx];
$y = $input[$idx + 1];
$x_param = $x[$key];
$y_param = $y[$key];
if (is_null($y)) {
$end = true;
continue;
}
if ($order == "desc"){
if ($x_param < $y_param){
$input[$idx] = $y;
$input[$idx + 1] = $x;
$swapped = true;
}
}
else{
if ($y_param < $x_param){
$input[$idx] = $y;
$input[$idx + 1] = $x;
$swapped = true;
}
}
$idx++;
}
while ($end == false);
if ($swapped == false) {break;}
}
return $input;
}
在這個例子中,我將在這個關聯數組上使用它:
$array = array(
array("Student Number" => 001, "Student name" => "David", "Student age" => 21),
array("Student Number" => 002, "Student name" => "Jonas", "Student age" => 15),
array("Student Number" => 003, "Student name" => "Katy", "Student age" => 23));
如果我像這樣用 print_r 打印它,它將成功排序並打印它:
print_r(bubbleSort($array, "Student age", "desc"));
問題是我收到通知:未定義偏移量:3對於包含$y = $input[$idx + 1]; 的行。
以及注意:嘗試訪問包含$y_param = $y[$key]的行的null 類型值的數組偏移量;
它確實打印了一個正確排序的 asc 數組,因此代碼可以工作。
但是有沒有辦法來表達我的代碼而不收到通知?
您可以使用 usort 編寫自己的比較函數。
<?php
$array = array(
array("Student Number" => 001, "Student name" => "David", "Student age" => 21),
array("Student Number" => 002, "Student name" => "Jonas", "Student age" => 15),
array("Student Number" => 003, "Student name" => "Katy", "Student age" => 23)
);
function sort_array_by_key(&$array, $key, $order = 'ASC') {
usort(
$array,
fn($a, $b) => $order == 'ASC'
? $a[$key] <=> $b[$key]
: $b[$key] <=> $a[$key]
);
}
sort_array_by_key($array, 'Student name', 'DESC');
var_export($array);
輸出:
array (
0 =>
array (
'Student Number' => 3,
'Student name' => 'Katy',
'Student age' => 23,
),
1 =>
array (
'Student Number' => 2,
'Student name' => 'Jonas',
'Student age' => 15,
),
2 =>
array (
'Student Number' => 1,
'Student name' => 'David',
'Student age' => 21,
),
)
刪除上升/下降部分以便於閱讀:
function sort_array_by_key_asc(&$array, $key) {
usort(
$array, function($a, $b) use ($key) {
return $a[$key] <=> $b[$key];
}
);
}
(短箭頭函數吸收周圍的范圍,因此對作者來說可以不那么冗長。)
從ussort聯機幫助頁:
注意:如果兩個成員比較相等,則它們在排序數組中的相對順序未定義。
注意:此函數為數組中的元素分配新鍵。 它將刪除可能已分配的任何現有鍵,而不僅僅是重新排序鍵。
解決您未定義的索引。 您需要檢查它們是否存在。
所以而不是:
$x = $input[$idx];
$y = $input[$idx + 1];
$x_param = $x[$key];
$y_param = $y[$key];
if (is_null($y)) {
$end = true;
continue;
}
你會想要更像:
if(!array_key_exists($idx + 1, $input)) {
$end = true;
continue;
}
$y = $input[$idx + 1];
$x_param = $x[$key];
$y_param = $y[$key];
但是,請注意,您不是在檢查其他密鑰的有效性。 並且假設您有一個帶有順序索引的基於零的數字索引數組。 因此,您可能需要進一步檢查,或使用另一種方法來遍歷數組。
冒泡排序方法的替代方法是使用array_multisort並依靠它來完成繁重的工作。
根據您選擇的鍵提取一列值。 然后可以使用該列的排序對父數組進行排序。
底層算法是快速排序(我相信)。 這是使用 SORT_REGULAR(默認值)作為比較。 您需要查找排序標志。
<?php
$array = array(
'foo' => array("Student Number" => 001, "Student name" => "David", "Student age" => 21),
'bar' => array("Student Number" => 002, "Student name" => "Jonas", "Student age" => 15),
'baz' => array("Student Number" => 003, "Student name" => "Katy", "Student age" => 23)
);
function sort_by_key(&$array, $key, $reverse = false) {
$column = [];
foreach($array as $v) {
$column[] = $v[$key] ?? null;
}
$order_flag = $reverse ? SORT_DESC : SORT_ASC;
array_multisort($column, $order_flag, $array);
}
sort_by_key($array, 'Student age');
var_export($array);
輸出:
array (
'bar' =>
array (
'Student Number' => 2,
'Student name' => 'Jonas',
'Student age' => 15,
),
'foo' =>
array (
'Student Number' => 1,
'Student name' => 'David',
'Student age' => 21,
),
'baz' =>
array (
'Student Number' => 3,
'Student name' => 'Katy',
'Student age' => 23,
),
)
您總是會發現,如果您有相似的值,那么您可能想要進一步對另一列進行排序,依此類推。
您可以將上面的 foreach 換成 array_column() 調用,並在 array_multisort 中使用多列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.