我正在尝试对国家/地区数组进行排序,以便包含“美国”(id
1) 的行首先出现,而其他所有国家/地区均按字母顺序排序。
如何使用数组的 usort()
函数对除美国之外的所有内容进行排序以保持在顶部?
也欢迎任何替代建议。这是我当前的代码:
while (list($key, $value) = each($countries->countries)) {
$countries_array[] = array('id' => $key, 'text' => $value['countryname']);
}
function text_cmp($a, $b) {
return strcmp($a["text"], $b["text"]);
}
usort($countries_array, 'text_cmp');
最佳答案
一般来说,您可以重新设置数组的键,然后按键排序,然后将重新设置键的数组与具有单独 US 行的数组合并,然后重新索引该数组。然而,我不推荐它,因为这个过程中所需的迭代次数太高了,没有吸引力。换句话说,时间复杂度不是最优的。
$keyed = array_column($countries, null, 'text');
ksort($keyed);
var_export(array_values(['United States' => $keyed['United States']] + $keyed));
您还可以使用 array_column()
调用 array_search()
来隔离 text
值,但需要按字母顺序对列进行排序无论如何。因此,出于效率原因,我再次排除这种情况。我也不推荐任何使用 in_array()
的方法。
事实是,此任务只需调用一次 usort()
即可完成。
代码:(Demo)
usort(
$countries,
fn($a, $b) =>
[$a['text'] !== 'United States', $a['text']]
<=>
[$b['text'] !== 'United States', $b['text']]
);
var_export($countries);
通过在飞船运算符左侧提供 $a
数据并在右侧提供 $b
数据,ASC 排序会下降。
bool 值的升序排序将 false
置于 true
之前。为了确保 US 行始终比任何其他行具有更高的优先级,请检查 text
值是否不是 United States
。
宇宙飞船运算符每一侧的第一个元素是第一条规则。当两个 text
值都不是 United States
时,将应用标准字母顺序排序。
这是一种高效的方法,因为没有迭代的函数调用。
最后,由于您正在循环内从 $countries
对象的 countries
属性生成新的特定数组结构,因此您可以更好地利用该结构环形。也许是这样的:
$result = [];
foreach ($countries->countries as $id => ['countryname' => $text]) {
$row = compact(['id' 'text']);
if ($text === 'United States') {
$result[] = $row;
} else {
$theRest[] = $row;
$texts[] = $text;
}
}
array_multisort($texts, $theRest);
array_push($result, ...$theRest);
var_export($result);
关于php - 在单列上按字母顺序对行数组进行排序,但一个值必须始终位于第一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22791371/