suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Wie sortiere ich Arrays und Daten in PHP?

Diese Frage ist als Referenz zu Problemen bei der Array-Sortierung in PHP gedacht. Es ist leicht zu glauben, dass Ihr spezieller Fall einzigartig ist und eine neue Frage verdient, aber die meisten davon sind tatsächlich nur geringfügige Variationen einer der Lösungen auf dieser Seite.

Wenn Ihre Frage als Duplikat dieser Frage geschlossen wurde, bitten Sie bitte nur dann um erneutes Öffnen Ihrer Frage, wenn Sie erklären können, warum sie sich erheblich von allen folgenden Fragen unterscheidet.

Wie sortiere ich ein Array in PHP?

Wie sortiere ich ein komplexesArray in PHP?

Wie sortiere ich ein Array von Objekten in PHP?


  1. Grundlegendes eindimensionales Array; Mehrdimensionale Arrays, inkl. Array von Objekten enthält. Sortieren Sie ein Array basierend auf einem anderen Array

  2. Verwenden Sie die SPL-Sortierung

  3. Stabile Sortierung

Eine praktische Antwort unter Verwendung der vorhandenen PHP-Funktionen finden Sie unter 1. Eine wissenschaftlich detaillierte Antwort zu Sortieralgorithmen (die PHP-Funktionen implementieren und die Sie möglicherweise in sehr, sehr komplexen Fällen benötigen) finden Sie unter 2.

P粉068174996P粉068174996408 Tage vor656

Antworte allen(2)Ich werde antworten

  • P粉476475551

    P粉4764755512023-10-18 13:03:18

    好吧,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

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

    其他类型的排序

    冒泡排序

    摘自关于冒泡排序的维基百科文章:

    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;
    }

    选择排序

    摘自有关选择排序的维基百科文章:

    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;
    }

    插入排序

    摘自关于插入排序的维基百科文章:

    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 的维基百科文章:

    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;
    }

    梳排序

    摘自关于梳状排序的维基百科文章:

    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;
    }

    合并排序

    来自关于合并排序的维基百科文章:

    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;
    }

    快速排序

    摘自关于快速排序的维基百科文章:

    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 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;
    }

    Antwort
    0
  • P粉952365143

    P粉9523651432023-10-18 09:01:08

    基本一维数组

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

    适用的排序函数:

    • 排序
    • 排序
    • 分类
    • 排序
    • 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' => ...),
        ...
    );

    如果您想按每个条目的键“foo”对$array进行排序,则需要一个自定义比较函数。上面的 sort 和相关函数适用于它们知道如何比较和排序的简单值。 PHP 并不简单地“知道”如何处理像 array('foo' => 'bar', 'baz' => 42) 这样的复杂值;所以你需要告诉它。

    为此,您需要创建一个比较函数。该函数接受两个元素,如果认为这些元素相等,则必须返回 0;如果第一个值较低,则必须返回低于 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($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'];
    }

    感谢数学的力量,这将返回一个值 < 0、0 或 > 0,具体取决于 $a 是否小于、等于或大于 $b.

    请注意,这对于 float 值不起作用,因为它们会被简化为 int 并失去精度。请改用显式 -101 返回值。

    对象

    如果你有一个对象数组,它的工作方式是相同的:

    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 的预期,它返回 -10 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'];
        }
    }

    对于熟悉的人来说,这相当于使用 ORDER BY foo, baz 的 SQL 查询。
    另请参阅这个非常简洁的速记版本如何为任意数量的键动态创建这样的比较函数

    按手动静态顺序排序

    如果您想将元素排序为“手动顺序”,例如“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);

    您还可以按任一方向对多个列进行排序:

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

    从 PHP 7.0.0 开始,您还可以从对象数组中提取属性。


    Antwort
    0
  • StornierenAntwort