首頁  >  問答  >  主體

PHP中如何對數組和資料進行排序?

這個問題旨在作為 PHP 中數組排序問題的參考。人們很容易認為您的特定案例是獨特的並且值得提出新問題,但大多數實際上只是此頁面上的解決方案之一的微小變化。

如果您的問題因與此問題重複而關閉,請僅在您能解釋為什麼它與以下所有問題顯著不同的情況下才要求重新打開您的問題。

如何在 PHP 中對陣列進行排序?

如何在 PHP 中對複雜陣列進行排序?

如何在 PHP 中對物件數組進行排序?


  1. 基本一維數組;包括。多維數組,包括。物件數組;包括。根據另一個數組對一個數組進行排序

  2. 使用 SPL 排序

  3. 穩定排序

有關使用PHP 現有函數的實際答案,請參閱1.,有關排序演算法的學術詳細答案(PHP 函數實現的以及您可能在非常非常複雜的情況下需要的),參見2。

P粉068174996P粉068174996338 天前548

全部回覆(2)我來回復

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

    回覆
    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 開始,您也可以從物件陣列中提取屬性。


    回覆
    0
  • 取消回覆