尝试按具有特殊字符的子值对多维数组进行排序
Trying to sort a multidimensional array, by a sub-value with special characters
我曾经有一个包含国家列表的 PHP 数组:
$countries = array(
'AX' => 'Åland Islands',
'AF' => 'Afghanistan',
'GB' => 'United Kingdom'
);
$collator = collator_create('en');
collator_asort($collator, $countries, Collator::SORT_STRING);
显然这个列表对于这个例子来说要短得多,但是这里的排序是有效的。我期望并得到:
- 阿富汗
- 奥兰群岛
- 英国
但是,我需要添加更多的数据,它变成了多维的:
$countries = array(
array(
'name' => 'Åland Islands',
'code' => 'AX'
),
array(
'name' => 'Afghanistan',
'code' => 'AF'
),
array(
'name' => 'United Kingdom',
'code' => 'GB'
)
);
usort($countries, function($a, $b){ return $a['name'] <=> $b['name']; });
它对列表中的每个其他国家/地区进行排序,但给了我这个:
- 阿富汗
- 英国
- 奥兰群岛
我这辈子都想不出如何正确地对它进行排序。我意识到在当前状态下没有调用或应用整理器,但是有没有办法让整理器在多维环境中工作?
要在没有 Collator
的情况下对 "country list" 进行排序,您应该将所有带有 accented 字符的单词转换为它的 ASCII
演示文稿(例如 Å
到 A
)通过使用 iconv
函数:
usort($countries, function($a, $b){
return strcasecmp(iconv('utf-8', 'ascii//TRANSLIT', $a['name']), iconv('utf-8', 'ascii//TRANSLIT', $b['name']));
});
print_r($countries);
输出:
Array
(
[0] => Array
(
[name] => Afghanistan
[code] => AF
)
[1] => Array
(
[name] => Åland Islands
[code] => AX
)
[2] => Array
(
[name] => United Kingdom
[code] => GB
)
)
以下是基于您的初始方法的可能修复方法:
usort($countries, function($a, $b) {
$collator = collator_create('en');
$arr = array($a['name'], $b['name']);
collator_asort($collator, $arr, Collator::SORT_STRING);
return array_pop($arr) == $a['name'];
});
为了在长列表上获得最佳性能,您可能希望在匿名函数范围之外仅实例化 $collator 一次。
在多维数组的情况下,我们可以使用collator_compare()
函数定义自定义排序函数:
$collator = new Collator('en');
usort($countries, function($a, $b) use ($collator) {
return $collator->compare($a['name'], $b['name']);
});
我曾经有一个包含国家列表的 PHP 数组:
$countries = array(
'AX' => 'Åland Islands',
'AF' => 'Afghanistan',
'GB' => 'United Kingdom'
);
$collator = collator_create('en');
collator_asort($collator, $countries, Collator::SORT_STRING);
显然这个列表对于这个例子来说要短得多,但是这里的排序是有效的。我期望并得到:
- 阿富汗
- 奥兰群岛
- 英国
但是,我需要添加更多的数据,它变成了多维的:
$countries = array(
array(
'name' => 'Åland Islands',
'code' => 'AX'
),
array(
'name' => 'Afghanistan',
'code' => 'AF'
),
array(
'name' => 'United Kingdom',
'code' => 'GB'
)
);
usort($countries, function($a, $b){ return $a['name'] <=> $b['name']; });
它对列表中的每个其他国家/地区进行排序,但给了我这个:
- 阿富汗
- 英国
- 奥兰群岛
我这辈子都想不出如何正确地对它进行排序。我意识到在当前状态下没有调用或应用整理器,但是有没有办法让整理器在多维环境中工作?
要在没有 Collator
的情况下对 "country list" 进行排序,您应该将所有带有 accented 字符的单词转换为它的 ASCII
演示文稿(例如 Å
到 A
)通过使用 iconv
函数:
usort($countries, function($a, $b){
return strcasecmp(iconv('utf-8', 'ascii//TRANSLIT', $a['name']), iconv('utf-8', 'ascii//TRANSLIT', $b['name']));
});
print_r($countries);
输出:
Array
(
[0] => Array
(
[name] => Afghanistan
[code] => AF
)
[1] => Array
(
[name] => Åland Islands
[code] => AX
)
[2] => Array
(
[name] => United Kingdom
[code] => GB
)
)
以下是基于您的初始方法的可能修复方法:
usort($countries, function($a, $b) {
$collator = collator_create('en');
$arr = array($a['name'], $b['name']);
collator_asort($collator, $arr, Collator::SORT_STRING);
return array_pop($arr) == $a['name'];
});
为了在长列表上获得最佳性能,您可能希望在匿名函数范围之外仅实例化 $collator 一次。
在多维数组的情况下,我们可以使用collator_compare()
函数定义自定义排序函数:
$collator = new Collator('en');
usort($countries, function($a, $b) use ($collator) {
return $collator->compare($a['name'], $b['name']);
});