我是这里的新手。有一个关于php排序的问题。我搜索了很多,但不幸的是找不到解决方案。我知道这很容易,但我不知道为什么找了几个小时都找不到。
我有一个这样的数组。它们有一个键"duty",我想对此进行某种排序,以便新数组包含-个与"duty"字段顺序排列的数组。
$arrayName = array(
array(
'name' => 'Dr. Hugo Lopez',
'duty' => 'Anesthesiologist',
'link' => ''
),
array(
'name' => 'Dr. Dario Garin',
'duty' => 'Orthopedic Specialist',
'link' => 'dr-dario-garin.php'
),
array(
'name' => 'Dr. Maclovio Yañez',
'duty' => 'Plastic Surgeon',
'link' => ''
),
array(
'name' => 'Melissa Bracker',
'duty' => 'Patient Liaison',
'link' => ''
),
array(
'name' => 'Dr. Diego Guzman',
'duty' => 'Cardiologist',
'link' => ''
),
array(
'name' => 'Ivan Arafat',
'duty' => 'Accountant',
'link' => ''
),
array(
'img-old' => 'jorge-fernandez.jpg',
'duty' => 'Hospital Administrator',
'link' => ''
),
);
我试过了:
usort($arrayName, function($a, $b) {
return $a['duty'] - $b['duty'];
});
但这会按照Duty字段的降序排列数组。
我想把它按优先顺序排列在值勤字段。比如:我会设置职责字段值的顺序,将其按护士、维护、医生、司机等类别排列。
我希望能够使用某种数组自己设置分类顺序。
sort($arrayName, $priority);
$priority = array( 'President', 'Vice President', 'Doctors', 'Nurse', 'Maintenance', 'Drivers');
我对PHP不太熟悉。如果我问的是基本问题,请原谅。
usort($arrayName, function (array $a, array $b) {
static $priority = array('President', 'Vice President', 'Doctors', 'Nurse', 'Maintenance', 'Drivers');
return array_search($a['duty'], $priority) - array_search($b['duty'], $priority);
});
此处进行详细解释:https://stackoverflow.com/a/17364128/476
老实说,我会改变你组织数据结构的方式——有很多小的低效率可能会在未来对你造成伤害。更自然的是,你的专业人员名单属于一个部门,而不是有一个描述他们角色的属性。如果将用户分组到以下数据结构中,则执行排序和其他"部门"级任务会变得容易得多,而不会使"用户"级任务变得更加困难。
$arry = array(
'Accountant' => array(
...
),
'Anesthesiologist' => array(
...
),
)
如果这不是一个选项。。你可以使用下面的函数。。但请注意,我不建议在任何生产场景中以这种方式对数据进行排序。它为您设置的每个优先级迭代整个用户列表,这是一种效率很低的排序方法。想象一个场景,你有100个优先级和1000个用户——这需要100*1000=100000次迭代才能简单地对数据进行优先级排序。最糟糕的是,它会以指数级的速度变慢。
无论如何,这是一个效率低下的解决方案。。
$priorities = array(
'Accountant',
'Cardiologist',
'Anesthesiologist',
);
$arrayName = array(
...
);
$r = sortDuties($arrayName, $priorities);
var_dump($r);
function sortDuties($userList, $priorities = array()) {
$newList = array();
foreach($priorities AS $priority) {
for($i = 0; $i < count($userList); $i++) {
if(isset($userList[$i]) && $userList[$i]['duty'] == $priority){
$newList[] = $userList[$i];
unset($userList[$i]);
}
}
}
return array_merge($newList, $userList);
}
因为isset()
(或我将演示的null合并(总是优于array_search()
,所以我建议您通过翻转优先级数组来准备查找数组。当任务不在优先级数组中时,您需要分配一个高于最高优先级值的数字——为此,只需使用count()
。
代码:(演示(
$array = [
['name' => 'Dr. Hugo Lopez', 'duty' => 'Anesthesiologist', 'link' => ''],
['name' => 'Dr. Dario Garin', 'duty' => 'Orthopedic Specialist', 'link' => 'dr-dario-garin.php'],
['name' => 'Dr. Maclovio Yañez', 'duty' => 'Plastic Surgeon', 'link' => ''],
['name' => 'Melissa Bracker', 'duty' => 'Patient Liaison', 'link' => ''],
['name' => 'Dr. Diego Guzman', 'duty' => 'Cardiologist', 'link' => ''],
['name' => 'Ivan Arafat', 'duty' => 'Accountant', 'link' => ''],
['name' => 'Jorge Fernandez', 'duty' => 'Hospital Administrator', 'link' => ''],
];
$lookup = array_flip(['Hospital Administrator', 'Plastic Surgeon', 'Orthopedic Specialist']);
$fallback = count($lookup);
usort($array, function ($a, $b) use ($lookup, $fallback) {
return ($lookup[$a['duty']] ?? $fallback) <=> ($lookup[$b['duty']] ?? $fallback);
});
var_export($array);
如果你想扩展基于name
的排序规则,宇宙飞船操作员会让它变得非常简单。事实是,名称字符串的解析比排序更难。我将把名称分成最多3个元素,然后颠倒它们的顺序;姓氏"名字"前缀";。
代码:(演示(
usort($array, function ($a, $b) use ($lookup, $fallback) {
$aName = array_reverse(preg_match('~^((?:[a-z]+'.)?) ?('S+) (.+)~i', $a['name'], $out) ? $out : ['', '', '']);
$bName = array_reverse(preg_match('~^((?:[a-z]+'.)?) ?('S+) (.+)~i', $b['name'], $out) ? $out : ['', '', '']);
return [$lookup[$a['duty']] ?? $fallback, ...$aName]
<=>
[$lookup[$b['duty']] ?? $fallback, ...$bName];
});
这是我的解决方案,不是最有效的,但它应该做到这一点,它应该考虑到未定义为优先级的职责问题。
$priority = array('Orthopedic Specialist', 'Hospital Administrator', 'Accountant', 'Anesthesiologist', 'Plastic Surgeon');
function dutySort(array &$array, array $priority) {
usort($array, function($a, $b) use ($priority) {
$aPriority = array_search($a['duty'], $priority);
$aPriority = ($aPriority !== false ? $aPriority : count($priority));
$bPriority = array_search($b['duty'], $priority);
$bPriority = ($bPriority !== false ? $bPriority : count($priority));
return ($aPriority < $bPriority) ? -1 : 1;
});
}
dutySort($array, $priority);