亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

PHP自定義排序:根據指定鍵手動排序數組

PHP自定義排序:根據指定鍵手動排序數組

PHP
森欄 2023-04-21 16:33:32
我有一個看起來像的數組$array = [    //...    'name' => ['value' => 'Raj KB'],    'street' => ['value' => 'Street ABC'],    'city' => ['value' => 'Dubai'],    'country_id' => ['value' => 'UAE'],    'region' => ['value' => 'DXB'],    'region_id' => ['value' => 11],    'zip_code' => ['value' => 12345],    'city_id' => ['value' => 22],    //...];我想對數組進行排序,以便鍵country_id, region, region_id, city,city_id連續出現,同時保留其他鍵的位置。預期產出 $array = [    //...    'name' => ['value' => 'Raj KB'],    'street' => ['value' => 'Street ABC'],    'country_id' => ['value' => 'UAE'],    'region' => ['value' => 'DXB'],    'region_id' => ['value' => 11],    'city' => ['value' => 'Dubai'],    'city_id' => ['value' => 22],    'zip_code' => ['value' => 12345],    //...];我試過:試驗 #1uksort($array, function ($a, $b) {  $order = ['country_id' => 0, 'region' => 1, 'region_id' => 2, 'city' => 3, 'city_id' => 4];  if (isset($order[$a]) && isset($order[$b])) {    return $order[$a] - $order[$b];  } else {    return 0;  }});var_dump($array);試驗 #2uksort($array, function ($a, $b) {  $order = ['country_id' => 0, 'region' => 1, 'region_id' => 2, 'city' => 3, 'city_id' => 4];  if (!isset($order[$a]) && !isset($order[$b])) {    return 0;  } elseif (!isset($order[$a])) {    return 1;  } elseif (!isset($order[$b])) {    return -1;  } else {    return $order[$a] - $order[$b];  }});var_dump($array);但其余訂單不再維護。所以我希望這些自定義字段以相同的順序出現,而不會破壞其他字段的位置。例如,name應該先出現等等。
查看完整描述

3 回答

?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

看起來你想要的東西很難用 PHP 的排序方法之一實現。此外,由于不匹配鍵的相對順序不應該改變,我們可以爭取比 O (nlogn)排序方法更好的時間復雜度。


因此,我建議編寫一個函數,對兩個數組 ( $array, $order) 進行一些迭代,以便按預期順序收集鍵/值對。這構成了O(n+m)時間復雜度,其中n和m是兩個數組的兩個大小。


這是功能:


function sortadjacent($array, $order) {

    $insertAt = 0;

    foreach($array as $key => $_) {

        if (isset($order[$key])) break;

        $insertAt++;

    }


    $special = [];

    foreach($order as $key => $_) {

        if (isset($array[$key])) $special[$key] = $array[$key];

    }


    $result = [];

    foreach($array as $key => $value) {

        if (!isset($order[$key])) $result[$key] = $value;

        else if (count($result) == $insertAt) $result = array_merge($result, $special);

    }


    return $result;

}

你會這樣稱呼它:


$result = sortadjacent($array, $order);

請注意,此函數不會對 進行更改$array,而是在新數組中返回預期結果。


查看完整回答
反對 回復 2023-04-21
?
烙印99

TA貢獻1829條經驗 獲得超13個贊

您的實現非常接近,但是您必須在比較函數中考慮這種情況,其中只有一個您想要的鍵存在,而其他任何鍵都不存在。如果你return 0在那種情況下,它們將在你的數組中的其他鍵中被破壞(因為它們在這種情況下的位置被認為是相等的)。


由于您還希望保留現有鍵的序列,并在之后插入其他“提取的”鍵country_id,因此您可以保留對原始排序順序的引用,并使用它來解析與country_id其他字段相關的排序順序(和其他字段之間以保持當前排序順序)


通過處理這兩種特殊情況以明確地對您希望自己依次出現的鍵進行排序,您將獲得滿足您要求的結果:


$order = ['country_id' => 1, 'region' => 2, 'region_id' => 3, 'city' => 4, 'city_id' => 5];

$preset_order = array_flip(array_keys($array));


uksort($array, function ($a, $b) use ($order, $preset_order) {

  if (isset($order[$a]) && isset($order[$b])) {

    return $order[$a] - $order[$b];

  } else if (isset($order[$a])) {

    return $preset_order['country_id'] - $preset_order[$b];

  } else if (isset($order[$b])) {

    return $preset_order[$a] - $preset_order['country_id'];

  } else {

    return $preset_order[$a] - $preset_order[$b];

  }

});

輸出:


array(8) {

  'name' =>

  array(1) {

    'value' =>

    string(6) "Raj KB"

  }

  'street' =>

  array(1) {

    'value' =>

    string(10) "Street ABC"

  }

  'country_id' =>

  array(1) {

    'value' =>

    string(3) "UAE"

  }

  'region' =>

  array(1) {

    'value' =>

    string(3) "DXB"

  }

  'region_id' =>

  array(1) {

    'value' =>

    int(11)

  }

  'city' =>

  array(1) {

    'value' =>

    string(5) "Dubai"

  }

  'city_id' =>

  array(1) {

    'value' =>

    int(22)

  }

  'zip_code' =>

  array(1) {

    'value' =>

    int(12345)

  }

}


查看完整回答
反對 回復 2023-04-21
?
阿波羅的戰車

TA貢獻1862條經驗 獲得超6個贊

PHP 使用Quicksort,因此您不能只為要排序的元素返回有意義的值。在我看來,在這里使用 uksort 是個壞主意,因為您必須使用數組的當前索引作為值,但這是不可能的,因為您無法從比較函數內部訪問舊數組的副本。您還需要知道第一個特殊值在哪個索引上。


所以我建議這樣做,因為我認為用 uksort 做你想做的事是不可能的:


function customSort($array)

{

    $order = ['country_id' => 0, 'region' => 1, 'region_id' => 2, 'city' => 3, 'city_id' => 4];

    $keyArray = array();

    $sortedArray = array();

    foreach ($array as $i => $value) {

        $keyArray[] = $i;

    }

    $counter = 0;

    $hasStarted = false;

    $insertLater = array();

    for ($i = 0; $i < count($keyArray); $i++) {

        if ($hasStarted) {

            if ($counter < count($order)) {

                $sortedArray[array_search($counter, $order)] = $array[array_search($counter, $order)];


                $counter++;

                if (!isset($order[$keyArray[$i]])) {

                    array_push($insertLater, ["key" => $keyArray[$i], "value" => $array[$keyArray[$i]]]);

                }

                continue;

            }

        }


        if (count($insertLater) > 0) {

            $itemToInsert = array_shift($insertLater);

            $sortedArray[$itemToInsert["key"]] = $itemToInsert["value"];


            if (!isset($order[$keyArray[$i]])) {

                array_push($insertLater, ["key" => $keyArray[$i], "value" => $array[$keyArray[$i]]]);

            }

            continue;

        }

        if (isset($order[$keyArray[$i]]) && !$hasStarted) {

            $sortedArray[array_search($counter, $order)] = $array[array_search($counter, $order)];

            $hasStarted = true;

            $counter++;

            continue;

        }

        $sortedArray[$keyArray[$i]] = $array[$keyArray[$i]];

    }

    return $sortedArray;

}

It's may

不是最好的解決方案,但它有效 O(n)。


查看完整回答
反對 回復 2023-04-21
  • 3 回答
  • 0 關注
  • 191 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號