#php #arrays #sorting
#php #массивы #сортировка
Вопрос:
У меня есть такой массив:
[
['number' => '419-1'],
['number' => '302-1'],
['number' => '102-1'],
['number' => '102-11'],
['number' => '203-1'],
['number' => '508-1'],
['number' => '105-1'],
['number' => '102-2'],
['number' => '302-2'],
]
Я хочу, чтобы вывод был таким:
[
['number' => '102-1'],
['number' => '102-2'],
['number' => '102-11'],
['number' => '105-1'],
['number' => '203-1'],
['number' => '302-1'],
['number' => '302-2'],
['number' => '419-1'],
['number' => '508-1']
]
Проблема в том, что число хранится в виде строки. Я хочу рассматривать число как целое. Сортировка должна выполняться численно. Не сравнение строк. Я пробовал с usort, но это не помогло.
Кто-нибудь, пожалуйста, может мне помочь?
Ответ №1:
Вы хотите естественным образом отсортировать значения массива, 1, 2, 10, 20
чтобы они не сортировались как числовая строка 1, 10, 2, 20
. Результаты которого должны быть одинаковыми в PHP 5 и PHP 7.
Вы можете использовать array_multisort
с флагами SORT_ASC
и SORT_NATURAL
вместе с array_column
для извлечения значений для сортировки.
Пример https://3v4l.org/BNCe5
PHP 5.5
array_multisort(array_column($ar, 'number'), SORT_ASC, SORT_NATURAL, $ar);
var_export($ar);
В качестве альтернативы вы можете использовать strnatcmp
with usort
.
PHP 5.3
usort($ar, function($a, $b) {
return strnatcmp($a['number'], $b['number']);
});
var_export($ar);
Результат
array (
0 =>
array (
'number' => '102-1',
),
1 =>
array (
'number' => '102-2',
),
2 =>
array (
'number' => '102-11',
),
3 =>
array (
'number' => '105-1',
),
4 =>
array (
'number' => '203-1',
),
5 =>
array (
'number' => '302-1',
),
6 =>
array (
'number' => '302-2',
),
7 =>
array (
'number' => '419-1',
),
8 =>
array (
'number' => '508-1',
),
)
Ответ №2:
$arr = [
['number' => '419-1'],
['number' => '419-11'],
['number' => '102-1'],
['number' => '203-1'],
['number' => '508-1'],
['number' => '105-1'],
['number' => '102-2'],
['number' => '302-2'],
];
usort($arr, function($a,$b){
$an = explode('-',$a['number']);
$bn = explode('-',$b['number']);
if($an[0] == $bn[0]){
return $an[1]*1 > $bn[1]*1;
}
return $an[0]*1 > $bn[0]*1;
});
print_r($arr);
Комментарии:
1. Это не сортируется должным образом. Если у меня есть элемент с [‘number’ => ‘102-11’], он будет предшествовать [‘number’ => ‘102-2″]. Я хочу отсортировать его численно.
2. Я отредактировал входной и выходной массив, о котором идет речь. Я не хочу сравнивать их как строку, мне нужно сравнить их как число.
3. Обновлено в соответствии с вашими наблюдениями.
4. Ваши решения тоже работают! но мне больше нравится первый ответ в виде одной строки. Спасибо!
5. @TejasGosai Действительно. У вас все гладко, и этот флаг SORT_NATURAL очень хорош!