Числовая сортировка массива со значениями смешанных типов - PullRequest
3 голосов
/ 31 октября 2011

У меня есть смешанный массив, подобный этому:

$fruits = array(
    "lemon",
    "Lemon",
    20,
    "banana",
    "apple",
    "121",
    40,
    50
);

А затем примените к нему функцию sort() следующим образом:

sort($fruits, SORT_NUMERIC);
foreach ($fruits as $key => $val) {
    echo "fruits[" . $key . "] = " . $val . "\n";
}

Теперь я не понимаю вывод:

fruits[0] = apple
fruits[1] = lemon
fruits[2] = banana
fruits[3] = Lemon
fruits[4] = 20
fruits[5] = 40
fruits[6] = 50
fruits[7] = 121

Пожалуйста, объясните, почему так отсортировано?

Ответы [ 3 ]

3 голосов
/ 31 октября 2011

OP, поскольку sort(); не очень хорошо работает с прописными и строчными буквами, почему бы вам не преобразовать все в строчные и затем отсортировать?1007 *

fruits[0] = 20
fruits[1] = 40
fruits[2] = 50
fruits[3] = 121
fruits[4] = apple
fruits[5] = banana
fruits[6] = lemon
fruits[7] = lemon
2 голосов
/ 31 октября 2011

в основном это должно сортировать от A до Z, затем по числовому порядку, но используя смешанный тип, функция не знает, как отсортировать массив и дать случайный результат ...

на странице руководства естьогромное предупреждение гласит:

Будьте осторожны при сортировке массивов со значениями смешанных типов, потому что sort () может привести к непредсказуемым результатам.

вы можете добавить параметр в функцию:

  • SORT_REGULAR - сравнивать элементы как обычно (не меняйте типы)

  • SORT_NUMERIC - сравнивать элементы численно

  • SORT_STRING - сравнивать элементы в виде строк

  • SORT_LOCALE_STRING - сравнивать элементы в виде строк на основе текущей локали.Добавленный в PHP 4.4.0 и 5.0.2, он использует системный языковой стандарт, который можно изменить с помощью setlocale ().

В соответствии с руководством здесь на php.net

Редактировать 1: Вероятно, вы можете получить лучший результат сортировки, используя флаг SORT_REGULAR, поскольку он не меняет тип переменной, а числа остаются числами, а строки остаются строками, но это будеттакже даст вам странный результат

fruits[0] = 121
fruits[1] = Lemon
fruits[2] = apple
fruits[3] = banana
fruits[4] = lemon
fruits[5] = 20
fruits[6] = 40
fruits[7] = 50

Я думаю, потому что он сравнивает код ASCII с буквами строк, а L до a b l ... 121 на первом месте, потому что вы написали его такстрока "121"

Редактировать 2:

Лучший способ продолжить - разделить типы: (таким образом php будет обрабатывать «121» как число ине строка, но вы можете просто решить это с помощью предложения if

<?php
$fruits = array("lemon","Lemon", 20, "banana", "apple","121",40,50);
$arr1=array();
$arr2=array();
      foreach($fruits as $key=>$val){
          if (is_numeric($val))
               array_push($arr1,$val); 
          else
              array_push($arr2,$val);
      }          
sort($arr1,SORT_NUMERIC);            
sort($arr2,SORT_LOCALE_STRING);
$fruits = array_merge($arr1,$arr2);
echo "<pre>";
foreach ($fruits as $key => $val) {
    echo "fruits[" . $key . "] = " . $val . "\n";
}
?>
1 голос
/ 31 октября 2011

Я полагаю, что с sort($array, SORT_NUMERIC) значения, которые не могут быть преобразованы в число, обрабатываются как 0 и сортируются таким образом.Поскольку все строки в вашем примере становятся 0, на самом деле не имеет значения, стоит ли lemon перед banana .Вот пример:

<?php
$fruits = array("alpha", "bravo", -1, -0.001, 0, 0.001, 1, "x-ray", "zulu");
shuffle($fruits); // randomly re-arrange the items in array
sort($fruits, SORT_NUMERIC);
print_r($fruits);
// output -- pass 1
Array
(
    [0] => -1
    [1] => -0.001
    [2] => 0
    [3] => alpha
    [4] => x-ray
    [5] => zulu
    [6] => bravo
    [7] => 0.001
    [8] => 1
)
// output -- pass 2
Array
(
    [0] => -1
    [1] => -0.001
    [2] => bravo
    [3] => zulu
    [4] => 0
    [5] => x-ray
    [6] => alpha
    [7] => 0.001
    [8] => 1
)
// output -- pass 3
Array
(
    [0] => -1
    [1] => -0.001
    [2] => x-ray
    [3] => zulu
    [4] => 0
    [5] => bravo
    [6] => alpha
    [7] => 0.001
    [8] => 1
)
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...