Как упорядочить многомерный массив PHP по одному из ключей его подмассива - PullRequest
0 голосов
/ 27 сентября 2019

У меня есть работающая система доставки, которую мне нужно представить в алфавитном порядке, отсортированном по городу, который является ключом в подмассиве.

Это массив:

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

Как я мог это сделать?

Ответы [ 4 ]

2 голосов
/ 27 сентября 2019

Вам нужно сохранить внешние ключи, используйте uasort().Я предпочитаю оператор космического корабля (трехстороннее сравнение) между двумя key() вызовами.

Код: ( Демо )

$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 +, вы можете использовать синтаксис стрелок внутри пользовательских функций.( Демо )

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

Подготовка к вызову array_multisort() непомерно отвратительна, ИМО.( Демо )

array_multisort(array_keys(array_merge(...array_values($options))), $options);
1 голос
/ 27 сентября 2019

Во-первых, создайте отдельный массив для каждого города и вставьте их в новый массив, например:

$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']);
});

Наконец, вы можете просто сделать foreach в $newOptions и отобразить все, что захотите, основываясь на ключах «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>

Дайте мне знать, помогло ли это вам.

0 голосов
/ 27 сентября 2019

Вы можете достичь этого во многих отношениях, вот мой путь Демо , надеюсь, это сработает для вас.

$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
        )

)
0 голосов
/ 27 сентября 2019

Хорошо, этот вид немного сложнее, так как нам нужно сохранить родительский ключ для каждого города.Итак, мы поступаем следующим образом:

  • Измените текущий массив, чтобы в его подмассиве был добавлен дополнительный parent_key, который будет выглядеть так:

    'option_3' => array (
        'Rio' => '18',
        'parent_key' => 'option_3'
    )
    
  • Теперь мы используем usort () , чтобы сравнить 2 подмассива с помощью name - strcmp () и вернуть результат.

  • Мы снова перебираем их и используем 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 в ключе-ключе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...