[英]PHP How to sort an array of objects based on priority order with a backup of alphabetical?
我有一個這樣的數組:
$sort_me = array(
array("file"=>"Desert.jpg"),
array("file"=>"Hello.jpg"),
array("file"=>"Test.jpg)
)
我想根據文件屬性按字母順序對這個數組進行排序。 為了使事情復雜化,我有一個可選數組:
$sort_order = array("Test.jpg", "Hello.jpg", "NotFound.jpg")
該數組將指定一些用戶定義的排序。 這些數組元素具有優先級,如果找到它們將按該順序放置。 與$sort_order
中的任何內容不匹配的其他元素應按字母順序排列在數組的末尾。
In javascript I would use call a sort function with a comparator function that takes 2 elements and returns a number to place the first object ahead or behind the second.
如何使用 PHP 做到這一點?
編輯
我嘗試了一些東西,但沒有成功。 (再次修改,將邏輯放到一個function中,並概括按哪個字段排序)
<?php
function sort_priority($sort_me, $sort_order, $field) {
function compare($a, $b) {
if ($sort_order) {
$ai = array_search($a[$field], $sort_order);
$bi = array_search($b[$field], $sort_order);
if ($ai !== false && $bi === false) {
return -1;
} else if ($bi !== false && $ai === false) {
return 1;
} else if ($ai !== false && $bi !== false) {
return $bi - $ai;
}
}
return $a[$field] < $b[$field] ? -1 : 1;
}
usort($sort_me, "compare");
}
$sort_order = array("Test.jpg", "Hello.jpg", "NotFound.jpg");
$sort_me = array(
array("file"=>"Test.jpg"),
array("file"=>"Desert.jpg"),
array("file"=>"Hello.jpg")
);
sort_priority($sort_me, $sort_order, "file");
echo json_encode($sort_me);
?>
這輸出
Notice: Undefined variable: sort_order in c:\workspace\test.php on line 10
預期的 output 是
[{"file":"Test.jpg"},{"file":"Hello.jpg"},{"file":"Desert.jpg"}]
我不知道如何compare
function 以正確使用特定於上下文的$sort_order
function。
編輯
我接受了一個答案,但為了完整起見,我想發布我最終得到的似乎可行的內容。 如果有人想發布更優雅的解決方案,我會考慮將其標記為已接受。 但這是我所擁有的:
<?php
function compare_priority($a, $b) {
global $g_order, $g_field;
if ($g_order) {
$ai = array_search($a[$g_field], $g_order);
$bi = array_search($b[$g_field], $g_order);
if ($ai !== false && $bi === false) {
return -1;
} else if ($bi !== false && $ai === false) {
return 1;
} else if ($ai !== false && $bi !== false) {
return $ai - $bi;
}
}
return $a[$g_field] < $b[$g_field] ? -1 : 1;
}
function sort_priority(&$sort_me, $sort_order, $field) {
global $g_order, $g_field;
$g_order = $sort_order;
$g_field = $field;
usort($sort_me, "compare_priority");
}
$sort_me = array(
array("file"=>"Z"),
array("file"=>"A"),
array("file"=>"Y"),
array("file"=>"B")
);
$sort_order = array("Z", "Y", "C");
sort_priority($sort_me, $sort_order, "file");
echo json_encode($sort_me);
?>
您可以像使用 javascript 一樣做同樣的事情。 usort ( http://ch2.php.net/manual/en/function.usort.php ) 允許您定義元素之間的自定義比較。
我修改了你的代碼,它似乎工作:
<?php
function test() {
$sort_me = array(
array("file"=>"Test.jpg"),
array("file"=>"Desert.jpg"),
array("file"=>"Hello.jpg")
);
global $sort_order;
$sort_order = array("Test.jpg" , "Hello.jpg", "NotFound.jpg");
function compare($a, $b) {
global $sort_order;
if (is_array($sort_order)) {
$ai = array_search($a["file"], $sort_order);
$bi = array_search($b["file"], $sort_order);
if ($ai !== false && $bi === false) {
return -1;
} else if ($bi !== false && $ai === false) {
return 1;
} else if ($ai !== false && $bi !== false) {
return $ai - $bi;
}
}
return $a["file"] < $b["file"] ? -1 : 1;
}
usort($sort_me, "compare");
echo json_encode($sort_me);
}
test();
?>
對於具有較少函數調用的最干凈的腳本,請將usort()
與 spaceship 運算符一起使用。
我遵循的技術遵循兩步邏輯(包含條件的第一步):
樣本輸入:
$sort_me = [
["file" => "Desert.jpg"],
["file" => "What.jpg"],
["file" => "Hello.jpg"],
["file" => "Test.jpg"],
["file" => "Goodness.jpg"],
];
$sort_order = ["Test.jpg", "Hello.jpg", "NotFound.jpg"];
處理代碼:(演示)
$lookup = array_flip($sort_order);
$fallback = count($sort_order);
usort($sort_me, function($a, $b) use ($lookup, $fallback) {
return [$lookup[$a['file']] ?? $fallback, $a['file']]
<=>
[$lookup[$b['file']] ?? $fallback, $b['file']];
});
var_export($sort_me);
輸出:
array (
0 =>
array (
'file' => 'Test.jpg',
),
1 =>
array (
'file' => 'Hello.jpg',
),
2 =>
array (
'file' => 'Desert.jpg',
),
3 =>
array (
'file' => 'Goodness.jpg',
),
4 =>
array (
'file' => 'What.jpg',
),
)
從 PHP7.4 開始,您可以使用箭頭函數語法將全局變量引入自定義函數的作用域中,而無需use()
聲明。
usort($sort_me, fn($a, $b) =>
[$lookup[$a['file']] ?? $fallback, $a['file']]
<=>
[$lookup[$b['file']] ?? $fallback, $b['file']]
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.