Как я могу сортировать массивы и данные в PHP?

Этот вопрос предназначен в качестве справочного материала для вопросов о сортировке массивов в PHP. Легко представить, что ваш конкретный случай уникален и заслуживает нового вопроса, но большинство из них на самом деле являются незначительными вариациями одного из решений на этой странице.

Если ваш вопрос закрыт как дубликат этого вопроса, пожалуйста, попросите, чтобы ваш вопрос был вновь открыт, только если вы можете объяснить, почему он заметно отличается от всего нижеприведенного.

Как мне отсортировать массив в PHP?
Как отсортировать сложный массив в PHP?
Как отсортировать массив объектов в PHP?


  1. Основные одномерные массивы; Включительно Многомерные массивы, в т.ч. массивы объектов; Включительно Сортировка одного массива на основе другого

  2. Сортировка с SPL

  3. Стабильный сорт

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

14 ответов

Решение

Основные одномерные массивы

$array = array(3, 5, 2, 8);

Применимые функции сортировки:

  • sort
  • rsort
  • asort
  • arsort
  • natsort
  • natcasesort
  • ksort
  • krsort

Разница между ними заключается лишь в том, сохраняются ли ассоциации ключ-значение (" a "функции), будь то сортировка от низкой к высокой или обратная (" r "), сортирует ли значения или ключи (" k ") и как он сравнивает значения (" nat "по сравнению с обычным). См. http://php.net/manual/en/array.sorting.php для обзора и ссылки на дополнительную информацию.

Многомерные массивы, в том числе массивы объектов

$array = array(
    array('foo' => 'bar', 'baz' => 42),
    array('foo' => ...,   'baz' => ...),
    ...
);

Если вы хотите отсортировать $array клавишей 'foo' каждой записи вам нужна пользовательская функция сравнения. Выше sort и связанные функции работают с простыми значениями, которые они умеют сравнивать и сортировать. PHP не просто "знает", что делать со сложным значением, таким как array('foo' => 'bar', 'baz' => 42) хоть; так что вы должны сказать это.

Для этого вам нужно создать функцию сравнения. Эта функция принимает два элемента и должна возвращать 0 если эти элементы считаются равными, значение ниже, чем 0 если первое значение ниже, а значение выше 0 если первое значение выше. Вот и все, что нужно:

function cmp(array $a, array $b) {
    if ($a['foo'] < $b['foo']) {
        return -1;
    } else if ($a['foo'] > $b['foo']) {
        return 1;
    } else {
        return 0;
    }
}

Часто вы захотите использовать анонимную функцию в качестве обратного вызова. Если вы хотите использовать метод или статический метод, посмотрите другие способы указания обратного вызова в PHP.

Затем вы используете одну из этих функций:

  • usort
  • uasort
  • uksort

Опять же, они отличаются только тем, сохраняют ли они сопоставления ключ-значение и сортируют по значениям или ключам. Прочитайте их документацию для деталей.

Пример использования:

usort($array, 'cmp');

usort возьмет два элемента из массива и вызовет ваш cmp работать с ними. Так cmp() будет вызван с $a как array('foo' => 'bar', 'baz' => 42) а также $b как другой array('foo' => ..., 'baz' => ...), Затем функция возвращается к usort какое из значений было больше или равны ли они. usort повторяет этот процесс, передавая различные значения для $a а также $b пока массив не отсортирован. cmp Функция будет вызываться много раз, по крайней мере, столько раз, сколько есть значений в $array с различными комбинациями значений для $a а также $b каждый раз.

Чтобы привыкнуть к этой идее, попробуйте это:

function cmp($a, $b) {
    echo 'cmp called with $a:', PHP_EOL;
    var_dump($a);
    echo 'and $b:', PHP_EOL;
    var_dump($b);
}

Все, что вы сделали, это определили собственный способ сравнения двух элементов, это все, что вам нужно. Это работает со всеми видами ценностей.

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

sort сортирует по ссылке и не возвращает ничего полезного!

Обратите внимание, что массив сортируется на месте, вам не нужно присваивать возвращаемое значение чему-либо. $array = sort($array) заменит массив на true, не с отсортированным массивом. Просто sort($array); работает.

Пользовательские числовые сравнения

Если вы хотите отсортировать по baz ключ, который является числовым, все, что вам нужно сделать, это:

function cmp(array $a, array $b) {
    return $a['baz'] - $b['baz'];
}

Благодаря PoWER OF MATH это возвращает значение < 0, 0 или> 0 в зависимости от того, $a меньше, равно или больше чем $b,

Обратите внимание, что это не будет хорошо работать для float значения, так как они будут уменьшены до int и потерять точность. Используйте явное -1, 0 а также 1 вместо этого возвращайте значения.

Объекты

Если у вас есть массив объектов, он работает так же:

function cmp($a, $b) {
    return $a->baz - $b->baz;
}

функции

Внутри функции сравнения вы можете делать все, что вам нужно, в том числе вызывать функции:

function cmp(array $a, array $b) {
    return someFunction($a['baz']) - someFunction($b['baz']);
}

Струны

Ярлык для первой версии сравнения строк:

function cmp(array $a, array $b) {
    return strcmp($a['foo'], $b['foo']);
}

strcmp делает именно то, что ожидается от cmp здесь возвращается -1, 0 или же 1,

Оператор космического корабля

В PHP 7 появился оператор космического корабля, который объединяет и упрощает равные / меньшие / большие, чем сравнения по типам:

function cmp(array $a, array $b) {
    return $a['foo'] <=> $b['foo'];
}

Сортировка по нескольким полям

Если вы хотите отсортировать в первую очередь по foo, но если foo равно для двух элементов сортировать по baz:

function cmp(array $a, array $b) {
    if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0) {
        return $cmp;
    } else {
        return $a['baz'] - $b['baz'];
    }
}

Для тех, кто знаком, это эквивалентно запросу SQL с ORDER BY foo, baz,
Также ознакомьтесь с этой очень аккуратной сокращенной версией и с тем, как динамически создать такую ​​функцию сравнения для произвольного числа ключей.

Сортировка в ручную, статический порядок

Если вы хотите отсортировать элементы в "ручной порядок", например, "foo", "bar", "baz":

function cmp(array $a, array $b) {
    static $order = array('foo', 'bar', 'baz');
    return array_search($a['foo'], $order) - array_search($b['foo'], $order);
}

Для всего вышеперечисленного, если вы используете PHP 5.3 или выше (и вы действительно должны), используйте анонимные функции для более короткого кода и во избежание появления другой глобальной функции:

usort($array, function (array $a, array $b) { return $a['baz'] - $b['baz']; });

Вот как может быть проста сортировка сложного многомерного массива. Опять же, просто подумайте с точки зрения обучения PHP, как определить, какой из двух элементов "больше"; позвольте PHP сделать фактическую сортировку.

Также для всего вышеперечисленного, для переключения между возрастающим и нисходящим порядком просто поменяйте местами $a а также $b споры вокруг. Например:

return $a['baz'] - $b['baz']; // ascending
return $b['baz'] - $a['baz']; // descending

Сортировка одного массива на основе другого

И тут есть своеобразный array_multisort, что позволяет сортировать один массив на основе другого:

$array1 = array( 4,   6,   1);
$array2 = array('a', 'b', 'c');

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

$array2 = array('c', 'a', 'b');  // the sorted order of $array1

использование array_multisort попасть туда:

array_multisort($array1, $array2);

Начиная с PHP 5.5.0 вы можете использовать array_column чтобы извлечь столбец из многомерного массива и отсортировать массив по этому столбцу:

array_multisort(array_column($array, 'foo'), SORT_DESC, $array);

Начиная с PHP 7.0.0 вы также можете извлекать свойства из массива объектов.


Если у вас есть более распространенные случаи, не стесняйтесь редактировать этот ответ.

Ну, большинство базовых методов уже охвачены deceze, я бы попробовал взглянуть на другие типы сортировки.

Сортировка с SPL

SplHeap

class SimpleHeapSort extends SplHeap {
    public function compare($a, $b) {
        return strcmp($a, $b);
    }
}

// Let's populate our heap here (data of 2009)
$heap = new SimpleHeapSort();
$heap->insert("a");
$heap->insert("b");
$heap->insert("c");

echo implode(PHP_EOL, iterator_to_array($heap));

Выход

c
b
a

SplMaxHeap

Класс SplMaxHeap обеспечивает основные функции кучи, сохраняя максимум на вершине.

$heap = new SplMaxHeap();
$heap->insert(1);
$heap->insert(2);
$heap->insert(3);

SplMinHeap

Класс SplMinHeap обеспечивает основные функциональные возможности кучи, сохраняя минимум сверху.

$heap = new SplMinHeap ();
$heap->insert(3);
$heap->insert(1);
$heap->insert(2);

Другие виды сортировки

Пузырьковая сортировка

Из статьи Википедии о Bubble Sort:

Пузырьковая сортировка, иногда неправильно называемая тонущей сортировкой, представляет собой простой алгоритм сортировки, который работает путем многократного пошагового перемещения по списку для сортировки, сравнения каждой пары смежных элементов и их замены, если они находятся в неправильном порядке. Проход по списку повторяется до тех пор, пока не понадобятся перестановки, что указывает на то, что список отсортирован. Алгоритм получил свое название от того, как меньшие элементы "всплывают" в верхнюю часть списка. Поскольку он использует только сравнения для работы с элементами, это сортировка сравнения. Хотя алгоритм прост, большинство других алгоритмов сортировки более эффективны для больших списков.

function bubbleSort(array $array) {
    $array_size = count($array);
    for($i = 0; $i < $array_size; $i ++) {
        for($j = 0; $j < $array_size; $j ++) {
            if ($array[$i] < $array[$j]) {
                $tem = $array[$i];
                $array[$i] = $array[$j];
                $array[$j] = $tem;
            }
        }
    }
    return $array;
}

Сортировка выбора

Из статьи Википедии о сортировке выбора:

В информатике сортировка по выбору - это алгоритм сортировки, в частности сортировка по месту. Он имеет O(n2) временную сложность, что делает его неэффективным в больших списках, и, как правило, работает хуже, чем аналогичный тип вставки. Сортировка выбора отличается простотой и имеет преимущества в производительности по сравнению с более сложными алгоритмами в определенных ситуациях, особенно в тех случаях, когда вспомогательная память ограничена.

function selectionSort(array $array) {
    $length = count($array);
    for($i = 0; $i < $length; $i ++) {
        $min = $i;
        for($j = $i + 1; $j < $length; $j ++) {
            if ($array[$j] < $array[$min]) {
                $min = $j;
            }
        }
        $tmp = $array[$min];
        $array[$min] = $array[$i];
        $array[$i] = $tmp;
    }
    return $array;
}

Вид вставки

Из статьи в Википедии о сортировке вставок:

Вставка сортировки - это простой алгоритм сортировки, который создает окончательный отсортированный массив (или список) по одному элементу за раз. Он гораздо менее эффективен в больших списках, чем более продвинутые алгоритмы, такие как быстрая сортировка, heapsort или сортировка слиянием. Тем не менее, вставка сортировки обеспечивает несколько преимуществ:

function insertionSort(array $array) {
    $count = count($array);
    for($i = 1; $i < $count; $i ++) {

        $j = $i - 1;
        // second element of the array
        $element = $array[$i];
        while ( $j >= 0 && $array[$j] > $element ) {
            $array[$j + 1] = $array[$j];
            $array[$j] = $element;
            $j = $j - 1;
        }
    }
    return $array;
}

ShellSort

Из статьи в Википедии о Shellsort:

Shellsort, также известный как сортировка Shell или метод Shell, является сортировкой сравнения на месте. Он обобщает обменную сортировку, такую ​​как вставка или пузырьковая сортировка, начиная сравнение и обмен элементами с элементами, которые находятся далеко друг от друга, прежде чем заканчивать соседними элементами.

function shellSort(array $array) {
    $gaps = array(
            1,
            2,
            3,
            4,
            6
    );
    $gap = array_pop($gaps);
    $length = count($array);
    while ( $gap > 0 ) {
        for($i = $gap; $i < $length; $i ++) {
            $tmp = $array[$i];
            $j = $i;
            while ( $j >= $gap && $array[$j - $gap] > $tmp ) {
                $array[$j] = $array[$j - $gap];
                $j -= $gap;
            }
            $array[$j] = $tmp;
        }
        $gap = array_pop($gaps);
    }
    return $array;
}

Расческа

Из статьи в Википедии о сортировке Расчески:

Сортировка с использованием гребня - это относительно простой алгоритм сортировки, первоначально разработанный Влодзимежем Добосевичем в 1980 году. Позже он был вновь открыт Стивеном Лейси и Ричардом Боксом в 1991 году. Сортировка с использованием гребенки улучшает пузырьковую сортировку.

function combSort(array $array) {
    $gap = count($array);
    $swap = true;
    while ( $gap > 1 || $swap ) {
        if ($gap > 1)
            $gap /= 1.25;
        $swap = false;
        $i = 0;
        while ( $i + $gap < count($array) ) {
            if ($array[$i] > $array[$i + $gap]) {
                // swapping the elements.
                list($array[$i], $array[$i + $gap]) = array(
                        $array[$i + $gap],
                        $array[$i]
                );
                $swap = true;
            }
            $i ++;
        }
    }
    return $array;
}

Сортировка слиянием

Из статьи в Википедии о сортировке слиянием:

В информатике сортировка слиянием (также обычно пишется как mergesort) - это алгоритм сортировки, основанный на сравнении O(n log n). Большинство реализаций производят стабильную сортировку, что означает, что реализация сохраняет порядок ввода одинаковых элементов в отсортированном выводе.

function mergeSort(array $array) {
    if (count($array) <= 1)
        return $array;

    $left = mergeSort(array_splice($array, floor(count($array) / 2)));
    $right = mergeSort($array);

    $result = array();

    while ( count($left) > 0 && count($right) > 0 ) {
        if ($left[0] <= $right[0]) {
            array_push($result, array_shift($left));
        } else {
            array_push($result, array_shift($right));
        }
    }
    while ( count($left) > 0 )
        array_push($result, array_shift($left));

    while ( count($right) > 0 )
        array_push($result, array_shift($right));

    return $result;
}

Quicksort

Из статьи в Википедии о быстрой сортировке:

Быстрая сортировка, или сортировка по разделу, представляет собой алгоритм сортировки, разработанный Тони Хоаром, который в среднем выполняет O(n log n) сравнений для сортировки n элементов. В худшем случае он делает O(n2) сравнений, хотя такое поведение встречается редко.

function quickSort(array $array) {
    if (count($array) == 0) {
        return $array;
    }
    $pivot = $array[0];
    $left = $right = array();
    for($i = 1; $i < count($array); $i ++) {
        if ($array[$i] < $pivot) {
            $left[] = $array[$i];
        } else {
            $right[] = $array[$i];
        }
    }
    return array_merge(quickSort($left), array(
            $pivot
    ), quickSort($right));
}

Перестановка сортировки

Из статьи Википедии о перестановочной сортировке:

Сортировка перестановок, которая продолжается путем генерации возможных перестановок входного массива / списка до обнаружения отсортированной.

function permutationSort($items, $perms = array()) {
    if (empty($items)) {
        if (inOrder($perms)) {
            return $perms;
        }
    } else {
        for($i = count($items) - 1; $i >= 0; -- $i) {
            $newitems = $items;
            $newperms = $perms;
            list($foo) = array_splice($newitems, $i, 1);
            array_unshift($newperms, $foo);
            $res = permutationSort($newitems, $newperms);
            if ($res) {
                return $res;
            }
        }
    }
}

function inOrder($array) {
    for($i = 0; $i < count($array); $i ++) {
        if (isset($array[$i + 1])) {
            if ($array[$i] > $array[$i + 1]) {
                return False;
            }
        }
    }
    return True;
}

Radix sort

Из статьи в Википедии о сортировке Radix:

В информатике радикальная сортировка - это не сравнительный алгоритм целочисленной сортировки, который сортирует данные по целочисленным ключам путем группировки ключей по отдельным цифрам, которые имеют одинаковые значимые позиции и значения.

// Radix Sort for 0 to 256
function radixSort($array) {
    $n = count($array);
    $partition = array();

    for($slot = 0; $slot < 256; ++ $slot) {
        $partition[] = array();
    }

    for($i = 0; $i < $n; ++ $i) {
        $partition[$array[$i]->age & 0xFF][] = &$array[$i];
    }

    $i = 0;

    for($slot = 0; $slot < 256; ++ $slot) {
        for($j = 0, $n = count($partition[$slot]); $j < $n; ++ $j) {
            $array[$i ++] = &$partition[$slot][$j];
        }
    }
    return $array;
}

Стабильный сорт

Допустим, у вас есть такой массив:

['Kale', 'Kaleidoscope', 'Aardvark', 'Apple', 'Leicester', 'Lovely']

А теперь вы хотите отсортировать только по первой букве:

usort($array, function($a, $b) {
    return strcmp($a[0], $b[0]);
});

Результат таков:

['Apple', 'Aardvark', 'Kale', 'Kaleidoscope', 'Lovely', 'Leicester']

Сорт не был стабильным!

Зоркий наблюдатель, возможно, заметил, что алгоритм сортировки массива (QuickSort) не дал стабильного результата и что первоначальный порядок между словами одной и той же первой буквы не сохранился. Этот случай тривиален, и мы должны были сравнить всю строку, но давайте предположим, что ваш вариант использования более сложный, например, два последовательных сортировки по разным полям, которые не должны отменять работу друг друга.

Преобразование Шварца

Преобразование Шварца, также называемое идиомой decorate-sort-undecorate, обеспечивает устойчивую сортировку с помощью изначально нестабильного алгоритма сортировки.

Сначала вы декорируете каждый элемент массива другим массивом, включающим первичный ключ (значение) и вторичный ключ (его индекс или позицию):

array_walk($array, function(&$element, $index) {
    $element = array($element, $index); // decorate
});

Это преобразует массив в это:

[
    ['Kale', 0], ['Kaleidoscope', 1], 
    ['Aardvark', 2], ['Apple', 3], 
    ['Leicester', 4], ['Lovely', 5]
]

Теперь настроим шаг сравнения; мы снова сравниваем первую букву, но если они совпадают, вторичный ключ используется для сохранения первоначального порядка:

usort($array, function($a, $b) {
    // $a[0] and $b[0] contain the primary sort key
    // $a[1] and $b[1] contain the secondary sort key
    $tmp = strcmp($a[0][0], $b[0][0]);

    if ($tmp != 0) {
        return $tmp; // use primary key comparison results
    }

    return $a[1] - $b[1]; // use secondary key
});

После этого мы декорируем:

array_walk($array, function(&$element) {
    $element = $element[0];
});

Конечный результат:

['Aardvark', 'Apple', 'Kale', 'Kaleidoscope', 'Leicester', 'Lovely']

Как насчет повторного использования?

Вы должны были переписать свою функцию сравнения для работы с преобразованными элементами массива; Вы можете не захотеть редактировать свои тонкие функции сравнения, поэтому вот обертка для функции сравнения:

function stablecmp($fn)
{
    return function($a, $b) use ($fn) {
        if (($tmp = call_user_func($fn, $a[0], $b[0])) != 0) {
            return $tmp;
        } else {
            return $a[1] - $b[1];
        }
    };
}

Давайте напишем шаг сортировки, используя эту функцию:

usort($array, stablecmp(function($a, $b) {
    return strcmp($a[0], $b[0]);
}));

Вуаля! Ваш первоначальный код сравнения вернулся.

Начиная с PHP 5.3 с замыканиями, также можно использовать замыкание для определения порядка вашего рода.

Например, предположим, что $array является массивом объектов, которые содержат свойство month.

 $orderArray = array("Jan","Feb","Mar","Apr","May","June","July","Aug","Sept","Oct","Nov","Dec");

 usort($array, function($a, $b) use ($orderArray){
       return array_search($a->month, $orderArray) - array_search($b->month, $orderArray);
 }); 

LINQ

В.NET LINQ часто используется для сортировки, что обеспечивает более приятный синтаксис по сравнению с функциями сравнения, особенно когда объекты должны быть отсортированы по нескольким полям. Существует несколько портов LINQ to PHP, включая библиотеку YaLinqo *. С его помощью массивы можно сортировать одной строкой без написания сложных функций сравнения.

$sortedByName         = from($objects)->orderBy('$v->name');
$sortedByCount        = from($objects)->orderBy('$v->count');
$sortedByCountAndName = from($objects)->orderBy('$v->count')->thenBy('$v->name');

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

$sortedByFilenameNat  = from($objects)->orderBy('$v->filename', 'strnatcmp');

Вот, '$v->count' это сокращение для function ($v) { return $v->count; } (может быть использован любой) Эти цепочки методов возвращают итераторы, итераторы можно преобразовать в массивы, добавив ->toArray() в конце при необходимости.

Внутренне orderBy и связанные методы вызывают соответствующие функции сортировки массива (uasort, krsort, multisort, usort так далее.).

LINQ содержит гораздо больше методов, основанных на SQL: фильтрация, группирование, объединение, агрегирование и т. Д. Он лучше всего подходит для случаев, когда необходимо выполнять сложные преобразования массивов и объектов без использования баз данных.

* разработанный мной, см. readme для более подробной информации и сравнения с другими портами LINQ

Эта страница очень обширна, но я хочу добавить немного больше об удивительной полезности оператора космического корабля (оператора трехстороннего сравнения) - прекрасного потомка PHP7+.

Использование оператора космического корабля для реализации нескольких условий сортировки

Это делает большие успехи в уменьшении раздувания кода и улучшении читаемости.

При написании пользовательской сортировки (usort()/uasort()/uksort()) для обработки нескольких условий, вам нужно только написать сбалансированные массивы по обе стороны от оператора и вернуть результат. Больше никаких вложенных блоков условий или множественных возвратов.

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

Примеры данных для моих демонстраций:

$multidimArray = [
    'a' => [
        'boolean' => true,
        'natString' => 'text10',
        'object' => (object)['prop' => 2],
        'float' => -.5,
        'mixed' => []
    ],
    'b' => [
        'boolean' => true,
        'natString' => 'text12',
        'object' => (object)['prop' => 4],
        'float' => 0,
        'mixed' => null
    ],
    'c' => [
        'boolean' => false,
        'natString' => 'text100',
        'object' => (object)['prop' => 9],
        'float' => -.5,
        'mixed' => false
    ],
    'd' => [
        'boolean' => true,
        'natString' => 'text1',
        'object' => (object)['prop' => 9],
        'float' => -5,
        'mixed' => "\0"
    ],
    'e' => [
        'boolean' => false,
        'natString' => 'text2',
        'object' => (object)['prop' => 2],
        'float' => .5,
        'mixed' => ''
    ]
];

Демонстрации (чтобы избежать раздувания страницы Stackru, см. Демонстрационную ссылку для выходных данных):

  • Логика сортировки:

    1. логическое DESC (ложь = 0, истина = 1, поэтому истина перед ложью)
    2. плавающий ASC

      uasort($multidimArray, function($a, $b) {
          return [$b['boolean'], $a['float']] <=> [$a['boolean'], $b['float']];
      });
      
  • Логика сортировки:

    1. смешанный ASC
    2. объект ASC
    3. логический ASC

      uasort($multidimArray, function($a, $b) {
          return [$a['mixed'], $a['object']->prop, $a['boolean']] <=> [$b['mixed'], $b['object']->prop, $b['boolean']];
      });
      
  • Логика сортировки:

    1. количество свойств объекта ASC
    2. итерабельность смешанного DESC
    3. длина natString ASC
    4. natString ASC

      uasort($multidimArray, function($a, $b) {
          return [count(get_object_vars($a['object'])), is_iterable($a['mixed']), strlen($a['natString']), $a['natString']]
                 <=>
                 [count(get_object_vars($b['object'])), is_iterable($b['mixed']), strlen($b['natString']), $b['natString']];
      });
      

Этот синтаксис позволяет элегантно сортировать значения, функциональные результаты, глубоко вложенные данные и направление сортировки. Это определенно стоит добавить в ваш набор инструментов php... для случаев, когда вы обрабатываете данные, не относящиеся к базе данных - потому что, конечно, SQL был бы гораздо более разумным методом.

По вашему усмотрению, начиная с PHP7.4, вы можете использовать синтаксис стрелок с этими анонимными функциями. Тот же сценарий с синтаксисом стрелок.

Многомерная сортировка по значению ключа

Естественная сортировка многомерного массива по значению ключа, а также сохранение исходного порядка (не перемешивайте основные ключи):

function multisortByKeyValue( $k, $arr ) {
    $ids   = array();
    $index = 1;

    foreach ( $arr as $key => $row ) {
        $ids[ $key ] = intval( $row[ $k ] ) . '-' . $index . '-' . $key;
        $index ++;
    }

    natsort( $ids );

    $arr = array_merge( $ids, $arr );

    return $arr;
}

Прецедент:

$arr = array(
    'id1' => array(
        'label'    => 'ID 1',
        'priority' => 30,
    ),
    'id2' => array(
        'label'    => 'ID 2',
        'priority' => 70,
    ),
    'id3' => array(
        'label'    => 'ID 3',
        'priority' => 20,
    ),
    'id4' => array(
        'label'    => 'ID 4',
        'priority' => 30,
    ),
);

$sorted = multisortByKeyValue( 'priority', $arr );

// $sorted equals to:
/*
array (
  'id3' => array (
    'label' => 'ID 3',
    'priority' => 20,
  ),
  'id1' => array (
    'label' => 'ID 1',
    'priority' => 30,
  ),
  'id4' => array (
    'label' => 'ID 4',
    'priority' => 30,
  ),
  'id2' => array (
    'label' => 'ID 2',
    'priority' => 70,
  ),
)
*/

Сортировать массивы с помощью отсортированной функции из Nspl очень удобно:

Базовая сортировка

// Sort array
$sorted = sorted([3, 1, 2]);

// Sort array in descending order
$sortedDesc = sorted([3, 1, 2], true);

Сортировка по результату функции

// Sort array by the result of a given function (order words by length)
$sortedByLength = sorted(['bc', 'a', 'abc'], 'strlen');
$sortedByLengthDesc = sorted(['bc', 'a', 'abc'], true, 'strlen');

// Sort array by the result of user-defined function (order words by the 1st character)
$sortedByTheFirstCharacter = sorted(['bc', 'a', 'abc'], function($v) { return $v[0]; }); 

// Which is the same as
$sortedByTheFirstCharacter = sorted(['bc', 'a', 'abc'], itemGetter(0));
$sortedByTheFirstCharacterDesc = sorted(['bc', 'a', 'abc'], true, itemGetter(0));

// itemGetter(0) returns a function which takes an argument with access by index/key
// and returns the value at index 0

Сортировка многомерного массива

// Sort multidimensional array (sort list of users by their names)
$users = [
    array('name' => 'Robert', 'age' => 20),
    array('name' => 'Alex', 'age' => 30),
    array('name' => 'Jack', 'age' => 25),
];
$sortedByName = sorted($users, itemGetter('name'));
$sortedByNameDesc = sorted($users, true, itemGetter('name'));

// itemGetter('name') returns a function which takes an argument with access by index/key
// and returns the value of the 'name' key

Сортировка массива объектов

// Lets assume we have class User(name, age) with properties name and age
// and public methods getName() and getAge()
$users = [
    new User('Robert', 20),
    new User('Alex', 30),
    new User('Jack', 25),
];

// Sort list of objects by property value (sort list of users by their name)
$sortedByName = sorted($users, propertyGetter('name'));
$sortedByNameDesc = sorted($users, true, propertyGetter('name'));

// propertyGetter('name') returns a function which takes an object
// and returns the value of its 'name' property

// Sort list of objects by method result (sort list of users by their age)
$sortedByAge = sorted($users, methodCaller('getAge'));
$sortedByAgeDesc = sorted($users, true, methodCaller('getAge'));

// methodCaller('getAge') returns a function which takes an object
// and returns the result of its getAge() method

Сортировка с функцией сравнения

// Sort with a comparison function (order words lexicographically with strcmp)
$sortedLexicographically = sorted(['bc', 'a', 'abc'], false, null, 'strcmp');

// Sort with user-defined comparison function (order words by the 1st character)
$sortedByTheFirstCharacter = sorted(['bc', 'a', 'abc'], false, null, function($v1, $v2) {
    return chr($v1[0]) - chr($v2[0]);
});

Вы можете увидеть все эти примеры здесь.

Если вы хотите заказать по значению ключа, то вы можете сделать это одной строкой, элегантно и понятно. Это будет порядок по возрастанию цены. Использует array_multisort и array_column.

   Array([0] => Array ( [name] => eggs [price] => 1 ) [1] => Array ( [name] => coffee [price] => 9.99 ) [2] => Array ( [name] => rice [price] => 4.04 ) )

   array_multisort (array_column($array, 'price'), SORT_ASC, $array);

производить

     Array ( [0] => Array ( [name] => eggs [price] => 1 ) [1] => Array ( [name] => rice [price] => 4.04 ) [2] => Array ( [name] => coffee [price] => 9.99 ) )

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

      usort($arr, function($item, $nextItem) {
    return (max($nextItem->firstNumber, $nextItem->secondNumber)) - (max($item->firstNumber, $item->secondNumber));
});

Пример:

      $foo = new stdClass;
$foo->createdDate = '10';
$foo->uploadedDate = '5';

$bar = new stdClass;
$bar->createdDate = '1';
$bar->uploadedDate = '12';

$baz = new stdClass;
$baz->createdDate = '25';
$baz->uploadedDate = '0';


$arr = [$foo, $bar, $baz];

// Order array by the highest number between "createdDate" and "uploadedDate".
usort($arr, function($item, $nextItem) {
    return (max($nextItem->createdDate, $nextItem->uploadedDate)) - (max($item->createdDate, $item->uploadedDate));
});

Результаты в:

      array (
  0 => 
  (object) array(
     'createdDate' => '25',
     'uploadedDate' => '0',
  ),
  1 => 
  (object) array(
     'createdDate' => '1',
     'uploadedDate' => '12',
  ),
  2 => 
  (object) array(
     'createdDate' => '10',
     'uploadedDate' => '5',
  ),
)

Есть несколько способов сортировки массива. Я упомяну некоторые методы для выполнения этой задачи. Из всех я приведу целочисленный массив, который называется "$numbers".

$number = array(8,9,3,4,0,1,2);

Это нормальный способ создания массива. Предположим, что я хочу отсортировать этот массив в порядке возрастания. Для этого можно использовать метод sort().

<?php

    $number = array(8,9,3,4,0,1,2);
    sort($number);

   foreach ($number as $value) {
       echo $value."  ";
   }
?>

Теперь рассмотрим вывод этого,

введите описание изображения здесь

Вы можете видеть, что напечатанный массив чисел отсортирован. Если вы хотите, чтобы этот числовой массив сортировался в порядке убывания, для этой задачи можно использовать метод rsort().

<?php

     $number = array(8,9,3,4,0,1,2);
     rsort($number);

     foreach ($number as $value) {
        echo $value."  ";
     }
?>

рассмотреть вывод..

введите описание изображения здесь

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

$number = array('eight'=>8,'nine'=>9,'three'=>3,'fore'=>4,'zero'=>0,'one'=>1,'two'=>2);

Итак, теперь я хочу отсортировать этот массив в порядке возрастания в соответствии с их значением. Для этого можно использовать метод 'asort()'.

<?php

   $number = array('eight'=>8,'nine'=>9,'three'=>3,'fore'=>4,'zero'=>0,'one'=>1,'two'=>2);
   asort($number);

   foreach ($number as $value) {
      echo $value."  ";
    }
?>

При сортировке в порядке убывания по их значению можно использовать метод "arsort()". Предположим, что вы хотите отсортировать этот массив по значению ключа. В этом случае можно использовать метод ksort().

<?php

     $number = array('eight'=>8,'nine'=>9,'three'=>3,'fore'=>4,'zero'=>0,'one'=>1,'two'=>2);
     ksort($number);

     foreach ($number as $value) {
         echo $value."  ";
     }
?>

Теперь рассмотрим вывод. введите описание изображения здесь

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

<?php

    $number = array('eight'=>8,'nine'=>9,'three'=>3,'fore'=>4,'zero'=>0,'one'=>1,'two'=>2);
    krsort($number);

    foreach ($number as $value) {
       echo $value."  ";
    }
?>

Теперь ассоциативный массив отсортирован в порядке убывания по значению ключа. Посмотрите на вывод. введите описание изображения здесь

Вот некоторые методы для сортировки массива в порядке возрастания или убывания в php. Я надеюсь, что вы могли бы получить представление. Спасибо!

Самое простое - использовать функцию usort для сортировки массива без зацикливания: ниже приведен пример:

   $array_compare= array("0" =>4,"1"=>2,"2"=>500,"3"=>100);

Это будет сортировать в порядке убывания:

usort($array_compare, function($a, $b) {
        return ($b['x1'] - $a['x1']) > 0 ? 1 :-1;
    });

Это будет сортировать в порядке возрастания:

usort($array_compare, function($a, $b) {
        return ($b['x1'] - $a['x1']) < 0 ? 1 :-1;
    });

Если кому-то нужно более простое решение для управления массивами, просто используйте пакет Laravel Collection, в котором есть реализованная функция sortBy, которая позволяет вам легко сортировать по ключам.

$collection->sortBy('forename')->sortBy('surname');

т.е. для сортировки сначала по a, затем по b, затем по c, правильным предложением будет

sortBy('c')->sortBy('b')->sortBy('a')

https://packagist.org/packages/tightenco/collect

Этот ответ касается сортировки по нескольким столбцам, когда массив должен быть отсортирован в каждом одномерном элементе по значениям несмежных индексов. Это отличается от многомерной сортировки, поскольку каждый элемент состоит только из различных пар Key=>Value.

      function fncCmp( array $ItmOne, array $ItmTwo ) {       ; # callback for sorting items (which are arrays) by values at specific indexes
  $strCmpOne = $ItmOne[ 'ColOne' ] . $ItmOne[ 'ColThr' ]; # build compound values
  $strCmpTwo = $ItmTwo[ 'ColOne' ] . $ItmTwo[ 'ColThr' ]; #   to compare
  return $strCmpOne <=> $strCmpTwo                      ; # pass back comparison-result
} # fncCmp

$arrDat = array(                                                       # define an array of items
  array( 'ColOne' => 'Val2', 'ColTwo' => 'Val8', 'ColThr' => 'Val6' )  #   each of which
 ,array( 'ColOne' => 'Val2', 'ColTwo' => 'Val9', 'ColThr' => 'Val4' )  #   is an
 ,array( 'ColOne' => 'Val1', 'ColTwo' => 'Val7', 'ColThr' => 'Val5' )  #   array of
)                                                                    ; #   fields
var_dump       ( $arrDat           )                                 ; # emit items before sort
$bolSrt = usort( $arrDat, 'fncCmp' )                                 ; # sort the array by comparing elements
var_dump       ( $arrDat           )                                 ; # emit items after  sort
Другие вопросы по тегам