我有一个这样的数组:
$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
中的任何内容不匹配的元素应按字母顺序排列在数组的末尾。
在javascript中我会使用一个带有比较器函数的sort函数,它接受2个元素并返回一个数字,将第一个对象放在第二个对象的前面或后面。
如何使用PHP执行此操作?
修改
我尝试了一些东西而且没用。 (再次修改以将逻辑放入一个函数,并概括要排序的字段)
<?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
预期输出
[{"file":"Test.jpg"},{"file":"Hello.jpg"},{"file":"Desert.jpg"}]
我不知道如何让compare
函数正确使用特定于上下文的$sort_order
函数。
修改
我接受了一个答案,但为了完整起见,我想发布我最终结束的内容似乎有效。如果有人想发布更优雅的解决方案,我会考虑将其标记为已接受。但这就是我所拥有的:
<?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);
?>
答案 0 :(得分:1)
你可以像使用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();
?>
答案 1 :(得分:0)
要使用更少的函数调用来获得最简洁的脚本,请将usort()
与飞船运算符配合使用。
我遵循的技术遵循两步逻辑(包含条件的第一步):
样本输入:
$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"];
处理代码:(Demo)
$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']]
);