按自定义顺序按键对数组进行排序


Sort array by keys in custom order

我有以下多维数组

[
    'June 2015' => [
        'LOW' => [160.50],
        'MEDIUM' => [0.00],
        'HIGH' => [60.80]
    ],
    'July 2015' => [
        'MEDIUM' => [226.00],
        'HIGH' => [263.00],
        'LOW' => [121.96]
    ]
]

我需要根据每个内部数组的键对它们进行排序,使它们按LOW、MEDIUM、HIGH的顺序排列(第一个偶然正确)。

我尝试了以下代码,并从这里进行了调整:

function cmp($a, $b){
        $a = preg_replace('@^(LOW|MEDIUM|HIGH) @', '', $a);
        $b = preg_replace('@^(LOW|MEDIUM|HIGH) @', '', $b);
        return strcasecmp($a, $b);
    }
    foreach($live_quotations as $exp_conversion_date => $Aconversion_likelihood){
        foreach($Aconversion_likelihood as $conversion_likelihood => $quotation_values){
    
            uksort($live_quotations[$exp_conversion_date], "cmp");
    
        }
    }

但这将它们排序为HIGH、MEDIUM、LOW(按字母顺序升序)。如果我更改cmp函数中的顺序,它们总是以这种方式排序,这并不重要。我认为我没有正确理解这个uksort或cmp函数。

您可以使用以下比较函数:

function cmp($a, $b) {
    $order = Array( 'LOW' => 0, 'MEDIUM' => 1, 'HIGH' => 2 );
    return $order[$a] - $order[$b];
}

这里是此代码的示例。

因为所有子数组都有三个指定的键,所以可以消除一些复杂性。内部循环可以省略,并且不需要排序算法。另外,如果您希望在缺少时建立默认元素,这也提供了该功能。

下面,您将建立一个有序数组,然后用每个出现的子数组值覆盖默认值。这可以通过"引用修改"来实现,但我遵循您发布的片段中的风格。

代码:(演示)

$ordered_defaults = array_fill_keys(['LOW', 'MEDIUM', 'HIGH'], 0);
foreach ($live_quotations as $date => $likelihoods) {
    $live_quotations[$date] = array_replace($ordered_defaults, $likelihoods);
}
var_export($live_quotations);

输出:

array (
  'June 2015' => 
  array (
    'LOW' => 
    array (
      0 => 160.5,
    ),
    'MEDIUM' => 
    array (
      0 => 0.0,
    ),
    'HIGH' => 
    array (
      0 => 60.8,
    ),
  ),
  'July 2015' => 
  array (
    'LOW' => 
    array (
      0 => 121.96,
    ),
    'MEDIUM' => 
    array (
      0 => 226.0,
    ),
    'HIGH' => 
    array (
      0 => 263.0,
    ),
  ),
)