Сортировать массив по алфавиту по определенной строке - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть этот массив планов:

Array
(
[0] => Array
    (
        [plan_id] => corporate-base
        [plan_name] => Tier 1 - NYC
    )

[1] => Array
    (
        [plan_id] => corporate-la-base
        [plan_name] => Tier 1 - LA
    )

[2] => Array
    (
        [plan_id] => corporate-sf-base
        [plan_name] => Tier 1 - SF
    )

[3] => Array
    (
        [plan_id] => corporate-core
        [plan_name] => Tier 2 - NYC
    )

[4] => Array
    (
        [plan_id] => corporate-la-core
        [plan_name] => Tier 2 - LA
    )

[5] => Array
    (
        [plan_id] => corporate-sf-core
        [plan_name] => Tier 2 - SF
    )

[6] => Array
    (
        [plan_id] => corporate-la-unlimited
        [plan_name] => Tier 3 - LA
    )

[7] => Array
    (
        [plan_id] => corporate-sf-unlimited
        [plan_name] => Tier 3 - SF
    )

[8] => Array
    (
        [plan_id] => corporate-unlimited
        [plan_name] => Tier 3 - NYC
    )

)

Я хочу, чтобы они были сгруппированы по городам, например:

Уровень 1 - LA

Уровень 2- LA

Уровень 3 - LA

Уровень 1 - NYC

Уровень 2 - NYC

Уровень 3 - NYC

Уровень 1- SF

Уровень 2 - SF

Уровень 3 - SF

Я пытался использовать array_multisort(), но сначала отображаются все уровни 1, затем уровень 2, а затемУровень 3.

В настоящее время я делаю 3 foreach петель, чтобы сгруппировать их в 3 города, но они не гибкие, и я думаю, что они слишком длинные.Что может быть самым быстрым / простым способом достижения этого?Спасибо!

1 Ответ

0 голосов
/ 20 февраля 2019

Вы можете использовать usort, используя функцию сортировки, которая извлекает название города из значения plan_name, используя explode.Если названия городов совпадают, мы извлекаем номер уровня, чтобы вместо этого можно было сортировать по нему:

usort($array, function ($a, $b) {
    $city_a = explode('-', $a['plan_name'])[1];
    $city_b = explode('-', $b['plan_name'])[1];
    if ($city_a == $city_b) {
        // sort by tier
        $tier_a = (int)explode(' ', $a['plan_name'])[1];
        $tier_b = (int)explode(' ', $b['plan_name'])[1];
        return $tier_a - $tier_b;
    }
    else {
        return strcmp($city_a, $city_b);
    }
});

Я не включил вывод, так как он довольно длинный, но вы можете увидеть его в этом демо на 3v4l.org

Это альтернативная версия, которая использует preg_match для извлечения города и уровня из каждого plan_name:

usort($array, function ($a, $b) {
    preg_match('/^Tier\s*(\d+)\s*-\s*(\w+)$/', $a['plan_name'], $matches_a);
    preg_match('/^Tier\s*(\d+)\s*-\s*(\w+)$/', $b['plan_name'], $matches_b);
    // are the cities the same?
    if ($matches_a[2] == $matches_b[2]) {
        // yes, sort by tier
        return $matches_a[1] - $matches_b[1];
    }
    else {
        // no, sort by city
        return strcmp($matches_a[2], $matches_b[2]);
    }
});

Демонстрация на 3v4l.org

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