簡體   English   中英

PHP 數組多重排序 - 按值然后按鍵?

[英]PHP array multiple sort - by value then by key?

我有一個帶有數值的字符串鍵數組,用於帶有每個標簽出現次數的標簽列表,因此:

$arrTags['mango'] = 2; 
$arrTags['orange'] = 4; 
$arrTags['apple'] = 2; 
$arrTags['banana'] = 3;

這樣我就可以按降序顯示標簽列表,因此:

orange (4)  
banana (3) 
mango (2) 
apple (2)

我可以使用arsort按很棒的值進行反向排序,但我也希望任何具有相同數值的標簽按字母順序排序,因此最終結果可以是:

orange (4)  
banana (3) 
apple (2) 
mango (2)

有沒有辦法做到這一點? 我猜usort可能是要走的路,但我看着 php.net 上的例子,我的眼睛呆滯了! 非常感謝!!!

正如 Scott Saunders 在他對 David 解決方案的評論中所暗示的那樣,您可以使用 array_keys() 和 array_values() 函數來擺脫循環。 事實上,你可以用一行代碼解決這個問題:

array_multisort(array_values($arrTags), SORT_DESC, array_keys($arrTags), SORT_ASC, $arrTags);

看看例子#3: http : //php.net/manual/en/function.array-multisort.php

您需要創建兩個數組以用作索引; 一個由原始數組的鍵和另一個原始數組的值組成。

然后使用 multisort 按文本值(原始數組的鍵)排序,然后按數值(原始數組的值)排序。

解決了

經過一些實驗,我發現array_multisort很好地完成了這個技巧:

$tag = array(); 
$num = array();

foreach($arrTags as $key => $value){ 
$tag[] = $key; 
$num[] = $value; 
}

array_multisort($num, SORT_DESC, $tag, SORT_ASC, $arrTags);

:)

先前提出的解決方案似乎合乎邏輯,但它不起作用:

ksort($arrTags);
arsort($arrTags);

實現查詢排序的完整 PHP 代碼為:

$k = array_keys($arrTags);
$v = array_values($arrTags);
array_multisort($k, SORT_ASC, $v, SORT_DESC);
$arrTags = array_combine($k, $v);

請注意,array_multisort() 在用戶輸入上使用引用,因此您必須使用兩個臨時變量($k 和 $v)來提供內容作為用戶輸入。 這樣 array_multisort() 可以改變內容。 稍后,通過 array_combine() 重建排序后的數組。

我已經構建了一個可重用的函數來完成這個任務:

<?php
/**
 * Sort a multi-dimensional array by key, then by value.
 *
 * @param array Array to be sorted
 * @param int One of the available sort options: SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING
 * @param int One of the available sort options: SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING
 * @return void
 * @example The following array will be reordered:
 *  $a = array(
 *      'd' => 4,
 *      'c' => 2,
 *      'a' => 3,
 *      'b' => 1,
 *      'e' => 2,
 *      'g' => 2,
 *      'f' => 2,
 *  );
 *  SortArrayByKeyThanValue($a);        # reorder array to: array(
 *      'b' => 1,
 *      'c' => 2,
 *      'e' => 2,
 *      'f' => 2,
 *      'g' => 2,
 *      'a' => 3,
 *      'd' => 4,
 *  );
 * @author Sijmen Ruwhof <sijmen(a)secundity.com>
 * @copyright 2011, Secundity
 */
function SortArrayByKeyThanValue (&$pArray, $pSortMethodForKey = SORT_ASC, $pSortMethodForValue = SORT_ASC)
{
    # check user input: sorting is not necessary
    if (count($pArray) < 2)
        return;

    # define $k and $v as array_multisort() needs real variables, as user input is put by reference
    $k = array_keys  ($pArray);
    $v = array_values($pArray);

    array_multisort(
        $v, $pSortMethodForValue,
        $k, $pSortMethodForKey
    );
    $pArray = array_combine($k, $v);
}
?>

SlappyTheFish 是正確的:使用 array_multisort 與 ksort,arsort

在 David 的示例 ksort 中,arsort 工作正常,但是如果鍵的字符串值包含字母字符以外的字符,則排序可能無法按預期工作。

前任:

$arrTags['banana'] = 3;
$arrTags['mango'] = 2;
$arrTags['apple1'] = 2;
$arrTags['orange'] = 4;
$arrTags['almond1'] = 2;

ksort($arrTags);
arsort($arrTags);

print_r($arrTags);

返回:

Array
(
    [orange] => 4
    [banana] => 3
    [apple1] => 2
    [mango] => 2
    [almond1] => 2
)

但是使用:

$arrTags['banana'] = 3;
$arrTags['mango'] = 2;
$arrTags['apple1'] = 2;
$arrTags['orange'] = 4;
$arrTags['almond1'] = 2;

$tag = array();
$num = array();

foreach($arrTags as $key => $value){
    $tag[] = $key;
    $num[] = $value;
}

array_multisort($num, SORT_DESC, $tag, SORT_ASC, $arrTags);


print_r($arrTags);

返回:

Array
(
    [orange] => 4
    [banana] => 3
    [almond1] => 2
    [apple1] => 2
    [mango] => 2
)
//preserve arrays keys for later use
$ar1= array_keys($your_array);

//preserve array's values for later use
$ar2= array_values($your_array);

//perform sorting by value and then by key
array_multisort($ar2, SORT_DESC, $ar1, SORT_DESC);

//combine sorted values and keys arrays to new array
$sorted_array = array_combine($ar1, $ar2);

一定沒問題。

使用uksort()將鍵傳遞到自定義函數的作用域中; 在該范圍內,使用傳入(完整)數組上的鍵訪問關聯值。

這樣做的好處是時間復雜度——這將比兩個單獨的排序函數調用更直接,並且不需要設置array_multisort()

盡管在提出這個問題時,宇宙飛船(3 路)操作員不可用,但現在可用,並且現在使比較更容易/更清晰。

從 PHP7.4 開始,語法非常簡潔。 演示

uksort($arrTags, fn($a, $b) => [$arrTags[$b], $a] <=> [$arrTags[$a], $b]);

從 PHP7.0 - PHP7.3 開始,您必須use()傳入主數組。 演示

uksort(
    $arrTags,
    function($a, $b) use ($arrTags) {
        return [$arrTags[$b], $a] <=> [$arrTags[$a], $b];
    }
);

你想的太復雜了:

ksort($arrTags);
arsort($arrTags);

現在您的數組已按照您希望的方式排序。

注意:此技術僅在 PHP7 及更高版本中可靠: https ://3v4l.org/ma7ab

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM