Меню сортировки массива - PullRequest
       13

Меню сортировки массива

0 голосов
/ 30 октября 2018

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

Массив выглядит следующим образом:

$menuArray = [
    'Main Street' => [
        ['/index.php', 'Home'],
        ['/city.php', $cityData[$user->city][0]],
        ['/travel.php', 'Travel'],
        ['/bank.php', 'Bank'],
        ['/inventory.php', 'Inventory'],
        ['/dailies.php', 'Dailies'],
    ],
    'Activities' => [
        (!$my->hospital) ? ['/hospital.php', 'Hospital'] : [],
        (!$my->hospital && !$my->prison) ? ['/crime.php', 'Crime'] : [],
        ['/missions.php', 'Missions'],
        ['/achievements.php', 'Achievements'],
    ],
    'Services' => [
        ['/hospital.php', 'Hospital'],
        ['/prison.php', 'Prison'],
        ['/search.php', 'Search'],
    ],
    'Account' => [
        ['/edit_account.php', 'Edit Account'],
        ['/notepad.php', 'Notepad'],
        ['/logout.php', 'Logout'],
    ]
];

У меня есть столбец menu_order, хранящийся в базе данных, который имеет значение по умолчанию 0,1,2,3,4, но это может измениться для каждого пользователя, так как они смогут изменить свое меню на «лайки».

Чего бы я хотел достичь:

0 => Main Street
1 => Activities
2 => Services
3 => Account
4 => Communication

Чтобы получить порядок меню, я делаю

$menuOrder = explode(',', $user->menu_order);

Но я не уверен, как обращаться с foreach для отображения меню.

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Вы можете попробовать что-то вроде этого, чтобы создать меню:

function display_menu($menus, $m) {
    if (!isset($menus[$m])) return;
    echo "<ul>";
    foreach ($menus[$m] as $item) {
        if (!count($item)) continue;
        echo "<li><a href=\"{$item[0]}\">{$item[1]}</a>\n";
    }
    echo "</ul>";
}
$menuMap = array(0 => 'Main Street',
1 => 'Activities',
2 => 'Services',
3 => 'Account',
4 => 'Communication');
$menuOrder = explode(',', $user->menu_order);
foreach ($menuOrder as $menuIndex) {
    $thisMenu = $menuMap[$menuIndex];
    display_menu($menuArray, $thisMenu);
}

Небольшая демонстрация на 3v4l.org

0 голосов
/ 30 октября 2018

Вот один из способов сделать это - использовать замену, а не алгоритм сортировки.

Код: ( Демо )

$menuArray = [
    'Main Street' => [],
    'Activities' => [],
    'Services' => [],
    'Account' => []
];
$lookup = [
    0 => 'Main Street',
    1 => 'Activities',
    2 => 'Services',
    3 => 'Account',
    4 => 'Communication'
];

$customsort = '4,2,1,3,0';

$keys = array_flip(explode(',', $customsort));  convert string to keyed array
//var_export($keys);

$ordered_keys = array_flip(array_replace($keys, $lookup));  // apply $lookup values to keys, then invert key-value relationship
//var_export($ordered_keys);

$filtered_keys = array_intersect_key($ordered_keys, $menuArray);  // remove items not on the current menu ('Communication" in this case)
//var_export($filtered_keys);

$final = array_replace($filtered_keys, $menuArray);  // apply menu data to ordered&filtered keys
var_export($final);

Выход:

array (
  'Services' => 
  array (
  ),
  'Activities' => 
  array (
  ),
  'Account' => 
  array (
  ),
  'Main Street' => 
  array (
  ),
)

А вот еще один способ использования uksort() и оператора космического корабля:

$ordered_keys = array_flip(array_values(array_replace(array_flip(explode(',', $customsort)), $lookup)));

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

Как следствие того, как вы храните свой пользовательский порядок сортировки, большая часть кода используется просто для настройки данных "map" / "lookup".

...