В php, как мне отсортировать массив путей на основе определенного (в данном случае последнего) фрагмента пути?

1

У меня такой массив:

[0] => /home/user/public_html/things/1 - First thing/
[1] => /home/user/public_html/things/3 - Third thing/
[2] => /home/user/public_html/things/2 - Second thing/

Какой простой способ отсортировать этот массив, чтобы 'things' шли 1, 2, 3?

Я использовал natsort() только для последнего фрагмента пути, но это не доказывает простоту использования... Я отрубил остальную часть пути, отсортировал, а затем вернул его, но это уродливо, и это может измениться в среднем так что я надеюсь на лучший способ, чем это.

Будем очень благодарны за любые предложения, я уверен, что есть несколько способов приблизиться к этому :)

  • 0
    usort() + basename()
  • 2
    В приведенном вами примере сортировка по всему пути или только по последней части даст тот же результат. Так почему бы вам просто не отсортировать пути такими, какие они есть? Или, если это не ваш случай, можете ли вы привести лучший пример в своем вопросе?
Показать ещё 1 комментарий
Теги:
arrays
fragment
sorting
path

4 ответа

1
Лучший ответ

Принимая во внимание ваш вопрос (сортируйте массив путей на основе определенного фрагмента пути), я подумал о функции, которая позволит вам указать фрагмент, который вы хотите отсортировать.

Поскольку пути в примере только отличаются в их последней части, это не очень интересно, если применить этот пример. Поэтому я буду использовать несколько другой список:

$paths = [
    '/home/user/public_html/things/sub/1',
    '/home/user/public_html/things/3',
    '/home/admin/public_html/things/2'
];

function build_sorter($part) {
    return function ($a, $b) use ($part) {
        return strnatcmp(
            implode("/", array_slice(explode("/", $a), $part)),
            implode("/", array_slice(explode("/", $b), $part))
        );
    };
}

// sort by second part in paths:
usort($paths, build_sorter(2));
print_r ($paths);

Созданный результат сначала помещает папку "admin":

   Array (
     [0] => /home/admin/public_html/things/2
     [1] => /home/user/public_html/things/3
     [2] => /home/user/public_html/things/sub/1
   ) 

Сортировка по последней части будет выглядеть так:

usort($paths, build_sorter(-1));
print_r ($paths);

Вывод:

   Array (
     [0] => /home/user/public_html/things/sub/1
     [1] => /home/admin/public_html/things/2
     [2] => /home/user/public_html/things/3
   ) 

Таким образом, аргумент, который вы передаете builder_sort представляет собой смещение (положительное слева, отрицательное справа) части путей, на которой вы хотите основать свою сортировку.

  • 0
    Это интересно, выглядит очень гибко. Я пытался взорваться> сделать что-то> взорваться ... Должна быть причина, почему я не просто сортировал массив путей, пример, который вы описываете, вероятно, так. Спасибо :)
  • 0
    Пожалуйста.
0

Я такой подход:

  1. найти первое целое в пути
  2. определить найденное значение int как ключ для текущего пути в новом массиве
  3. сортируйте новый массив с помощью ksort()

    $paths = [
        '/home/user/public_html/things/1 - First thing/',
        '/home/user/public_html/things/3 - Third thing/',
        '/home/user/public_html/things/2 - Second thing/'
    ];

    $matches = [];
    $sorted_paths = [];

    foreach ($paths as $path) {
        if (preg_match('/(\d+)/', $path, $matches)) {
            $sorted_paths[$matches[1]] = $path;
        }
    }

    ksort($sorted_paths);
    print_r($sorted_paths);

В результате у меня есть что-то вроде этого:

Array
(
    [1] => /home/user/public_html/things/1 - First thing/
    [2] => /home/user/public_html/things/2 - Second thing/
    [3] => /home/user/public_html/things/3 - Third thing/
)
  • 0
    Используйте целое число в качестве ключа для нового массива - отлично
  • 0
    (хотя я нахожу "1-е целое число в пути" немного неразборчивым)
Показать ещё 1 комментарий
0

Из того, что я понимаю, вы хотите отсортировать результаты массива по номеру после папки thingy.

<?php 
$Directories = array('/home/user/public_html/things/1', '/home/user/public_html/things/3', '/home/user/public_html/things/2');

$SortedNums = array();

foreach ( $Directories as $Dir )
{
    $Nums = explode("/", $Dir);

    foreach ( $Nums as $Num )
    {
        if ( is_numeric($Num) )
        {
            array_push($SortedNums, $Num);
        }   
    }
}

sort($SortedNums);

$ArrayLength=count($SortedNums);
for($x=0;$x<$ArrayLength;$x++)
{
   echo $SortedNums[$x];
   echo "<br>";
}
?>

Производит следующий вывод:

1 2 3

0

Применение asort- функции может это сделать.

$p = [
    '/home/user/public_html/things/1',
    '/home/user/public_html/things/3',
    '/home/user/public_html/things/2'
];

asort($p);

print_r($p);
  • 0
    Любое объяснение downvote?
  • 0
    Кажется, что вы удалили часть путей ...
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню