PHP сортировать подстроку массива

#php #arrays #sorting

#php #массивы #сортировка

Вопрос:

Я хочу отсортировать этот массив по годам:

 Array
(
    [0] => data/pictures/alice/1980
    [1] => data/pictures/alice/1985
    [2] => data/pictures/bob/1981
    [3] => data/pictures/bob/1985
    [4] => data/pictures/bob/1987
    [5] => data/pictures/bob/1989
)
 

Ожидаемый результат:

 Array
(
    [0] => data/pictures/alice/1980
    [1] => data/pictures/bob/1981
    [2] => data/pictures/alice/1985
    [3] => data/pictures/bob/1985
    [4] => data/pictures/bob/1987
    [5] => data/pictures/bob/1989
)
 

Я уже пробовал разные функции сортировки, но безуспешно.

Пример:

 asort($paths, SORT_STRING | SORT_FLAG_CASE);

sort($path, SORT_NUMERIC);
 

Комментарии:

1. Вы хотите посмотреть usort() .

Ответ №1:

Поскольку это путь, просто сопоставьте массив, basename() а затем отсортируйте на основе этого:

 array_multisort(array_map('basename', $paths), SORT_ASC, $paths);
 

Ответ №2:

Попробуйте это

 function cmp($a, $b) {
   // if equal, don't do much
   if ($a == $b) {
       return 0;
   }

   $explodedA = explode('/', $a);
   $explodedB = explode('/', $b);
   $yearPartA = $explodedA[count($explodedA) - 1];
   $yearPartB = $explodedB[count($explodedB) - 1];


   if ($explodedPartA == $explodedPartB) { // compare full string
      return ($a < $b) ? -1 : 1;
   }

   return ($yearPartA < $yearPartB) ? -1 : 1;
}

// actual sort of the array $path (e.g. the whole point)
usort($path, "cmp");
 

Однако учтите, что вы, вероятно, будете выполнять ‘explode’ несколько раз для каждого элемента массива и что может быть дешевле сначала немного поработать с массивом. Не уверен, насколько велик ваш массив… Проведите некоторое тестирование.

Комментарии:

1. Покажите usort на нем 🙂

2. Или он мог бы использовать substr от позиции последнего «/» до конца строки, но это может быть не более эффективно, чем взрыв.

3. верно… но на самом деле меня беспокоит та часть, где к элементам нужно обращаться хотя бы один раз…

Ответ №3:

 $array = ['data/pictures/alice/1980','data/pictures/alice/1985','data/pictures/bob/1981','data/pictures/bob/1985','data/pictures/bob/1987','data/pictures/bob/1989'];

uasort($array, function($a,$b) {
    $y1 = array_pop(explode('/', $a));
    $y2 = array_pop(explode('/', $b));
    if($y1===$y2) {
       // if year the same use other criteria
       if($a===$b) {
          return 0;
       }
       return $a>$b?-1:1;
    };
    return $y1>$y2?-1:1;
});
 

Комментарии:

1. приятный штрих с всплывающими окнами … однако обратите внимание на «проблему», когда годы одинаковы… я тоже пропустил это сначала. если на то пошло, я думаю, что пользователь также пропустил это, когда не рассматривал это.

2. «проблема», когда годы одинаковы — в чем проблема?

3. вы добавили ту часть, где это было проблемой, почему вы спрашиваете тогда? мы все можем видеть историю

Ответ №4:

Используйте usort и в пользовательской функции разнесите строки на «/» и сравните последние части массивов.