【问题标题】:How to order a PHP multidimensional array by one of its subarray's key如何通过其子数组的键之一对 PHP 多维数组进行排序
【发布时间】:2020-01-27 21:39:35
【问题描述】:

我有一个有效的交付系统,我需要按城市排序的字母顺序呈现,这是子数组中的键。

这是数组:

array (
    'option_3' => array (
        'Rio' => '18',
    ),
    'option_4' => array (
        'Tokyo' => '20',
    ),
    'option_5' => array (
        'Berlim' => '23',
    )
)

如下表所示:

<table>
    <tr>
        <th>ID</th>
        <th>Bairro</th>
        <th>Valor</th>
        <th>Ação</th>
    </tr>


[a foreach goes here]

    <tr>
        <td><?php echo $option_number;?></td>
        <td><?php echo $city;?></td>
        <td><?php echo $price;?></td>
        <td><button type='submit'>Remove</button></td>
    </tr>
<table>

这会产生以下结果:

ID  City  Value Action
3   Rio     18  Remover
4   Tokyo   20  Remover
5   Berlim  23  Remover

但我需要按城市排序:

ID  City  Value Action
5   Berlim  23  Remover
3   Rio     18  Remover
4   Tokyo   20  Remover

我怎样才能做到这一点?

【问题讨论】:

  • 先合并所有选项数组,然后对数组进行排序。所以你可以使用数组合并功能,然后你需要使用排序功能。之后,你想要的结果来了。

标签: php arrays sorting multidimensional-array


【解决方案1】:

首先,为每个城市创建一个数组并将它们推入一个新数组,如下所示:

$options = [
    'option_3' => [
        'Rio' => '18',
    ],
    'option_4' => [
        'Tokyo' => '20',
    ],
    'option_5' => [
        'Berlim' => '23',
    ]
];

$newOptions = [];

foreach($options as $key => $option) {
    array_push($newOptions, [
        'id' => $key,
        'city' => key($option),
        'price' => reset($option)
    ]);
}

之后,只需使用usort()按每个“城市”的值的字母顺序对其进行排序

usort($newOptions, function($a, $b) {
    return strcmp($a['city'], $b['city']);
});

最后,您可以简单地对$newOptions 执行一次 foreach 并根据键“id”、“city”和“price”回显您想要的任何内容。示例:

foreach($newOptions as $option)

<tr>
    <td><?php echo $option['id'];?></td>
    <td><?php echo $option['city']?></td>
    <td><?php echo $option['price']?></td>
    <td><button type='submit'>Remove</button></td>
</tr>

【讨论】:

    【解决方案2】:

    您需要保留外键,使用uasort()。我更喜欢两个key() 调用之间的宇宙飞船(3 向比较)运算符。

    代码:(Demo)

    $options = [
        'option_3' => [
            'Rio' => '18',
        ],
        'option_4' => [
            'Tokyo' => '20',
        ],
        'option_5' => [
            'Berlim' => '23',
        ]
    ];
    
    uasort($options, function ($a, $b) {
        return key($a) <=> key($b);
    });
    var_export($options);
    

    输出:

    array (
      'option_5' => 
      array (
        'Berlim' => '23',
      ),
      'option_3' => 
      array (
        'Rio' => '18',
      ),
      'option_4' => 
      array (
        'Tokyo' => '20',
      ),
    )
    

    从 PHP7.4+ 开始,您可以在自定义函数中使用箭头语法。 (Demo)

    uasort($options, fn($a, $b) => key($a) <=> key($b));
    

    array_multisort() 通话做准备是非常可怕的,IMO。 (Demo)

    array_multisort(array_keys(array_merge(...array_values($options))), $options);
    

    【讨论】:

    • 我还是觉得PHP7.4+版本看起来更像象形文字!
    【解决方案3】:

    您可以通过多种方式实现这一点,这是我的方式Demo,希望它对您有用。

    $arr = array (
        'option_3' => array (
            'Rio' => '18',
        ),
        'option_4' => array (
            'Tokyo' => '20',
        ),
        'option_5' => array (
            'Berlim' => '23',
        )
    );
    
    $cities = [];
    
    foreach($arr as $key=>$val){
        foreach($val as $key2=>$city){
    
            $option = explode('_', $key);
            $cities[$key2] = $city.'_'.$option[1];
        }
    }
    ksort($cities);
    
    $res = [];
    foreach($cities as $key=>$val){
        $temp = [];
        $temp['city'] = $key;
        $val_opt = explode('_', $val);
        $temp['value'] = $val_opt[0];
        $temp['option'] = $val_opt[1];
    
        $res[] = $temp;
    }
    
    print_r($res);
    

    输出:

    Array
    (
        [0] => Array
            (
                [city] => Berlim
                [value] => 23
                [option] => 5
            )
    
        [1] => Array
            (
                [city] => Rio
                [value] => 18
                [option] => 3
            )
    
        [2] => Array
            (
                [city] => Tokyo
                [value] => 20
                [option] => 4
            )
    
    )
    

    【讨论】:

      【解决方案4】:

      好的,这种排序有点棘手,因为我们还需要保留每个城市的父键。所以,我们如下:

      • 修改当前数组,使其子数组中有一个额外的 parent_key,如下所示:

        'option_3' => array (
            'Rio' => '18',
            'parent_key' => 'option_3'
        )
        
      • 现在,我们使用usort() 通过namestrcmp() 比较两个子数组并返回结果。

      • 我们再次遍历它们并使用array_keys() 遍历数据集。我们这样做是因为我们要恢复父键,而不会在迭代同一个数组时遇到并发修改问题。

      代码:

      <?php
      
      $data = array (
                  'option_3' => array (
                      'Rio' => '18',
                  ),
                  'option_4' => array (
                      'Tokyo' => '20',
                  ),
                  'option_5' => array (
                      'Berlim' => '23',
                  )
              );
      
      
      foreach($data as $key => &$value){
          $value['parent_key'] = $key;
      }
      
      
      usort($data,function($val1,$val2){
          $name1 = array_keys($val1)[0];
          $name2 = array_keys($val2)[0];
          return strcmp($name1,$name2); 
      });
      
      foreach(array_keys($data) as $index){
          $value = $data[$index];
          $parent_key = $value['parent_key'];
          unset($value['parent_key']); // unset parent key now as it is no longer needed
          $data[$parent_key] = $value;
          unset($data[$index]); // unset numeric index modified by usort()
      }
      
      
      print_r($data);
      

      演示: https://3v4l.org/q0YFk

      更新:当前结果不包含像 city 等额外的键,但在以键值方式执行 foreach 时很容易将其作为城市名称。

      【讨论】:

        猜你喜欢
        • 2012-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-02
        • 1970-01-01
        • 2012-06-10
        相关资源
        最近更新 更多