Получите отдельные ассоциативные массивы на основе вложенных пар ключ-значение - PullRequest
1 голос
/ 12 июля 2020

У меня в приложении есть система обмена сообщениями, и я вырываю волосы, пытаясь придумать, как лучше всего предоставить пользователю меню, чтобы выбрать, какую беседу они хотят прочитать. Я пытаюсь отразить меню стиля GroupMe, где слева находятся ваши разговоры. Этот список разговоров - динамический c, поэтому самые последние разговоры находятся вверху и обновляются, пока вы используете приложение.

Я использую Laravel 7 и Firebase

Вот данные из моего бэкэнда (предварительно заданные)

Array
(
    [-MC1kTfrrDHY3ZbidJ4Q] => Array
        (
            [from] => lSUfZ4sgEJd
            [message] => test message four no more!
            [startedAt] => 2020-07-12 11:21:10
            [to] => CWgPqdn3YweN
        )

    [-MC09BsjtXP0izITsThf] => Array
        (
            [from] => CWgPqdn3YweN
            [message] => test message three
            [startedAt] => 2020-07-11 11:20:19
            [subject] => -MC00BHCZlXUp25C5nlS
            [to] => lSUfZ4sgEJd
        )

    [-MC1kAi1niswXtjY_h4s] => Array
        (
            [from] => CWgPqdn3YweN
            [message] => test message two
            [startedAt] => 2020-07-12 11:19:52
            [to] => lSUfZ4sgEJd
        )

    [-MC1kOtfnIlAYtmJsD-a] => Array
        (
            [from] => CWgPqdn3YweN
            [message] => test message one
            [startedAt] => 2020-07-12 11:18:50
            [to] => lSUfZ4sgEJd
        )
     [-MC1kOtfnIlAhgcufu] => Array
        (
            [from] => CWgPqdn3YweN
            [message] => test message zero
            [startedAt] => 2020-07-12 11:00:50
            [to] => YLisXjk07w93
        )
)

Я хочу получать самые свежие, четкие разговоры, независимо от того, отправитель я или получатель. Конечный результат, который я хочу, будет выглядеть так:

Array
(
 [-MC1kTfrrDHY3ZbidJ4Q] => Array
        (
            [from] => lSUfZ4sgEJd
            [message] => test message four no more!
            [startedAt] => 2020-07-12 11:21:10
            [to] => CWgPqdn3YweN
        )
 [-MC1kOtfnIlAhgcufu] => Array
        (
            [from] => CWgPqdn3YweN
            [message] => test message zero
            [startedAt] => 2020-07-12 11:00:50
            [to] => YLisXjk07w93
        )
)

Кто-нибудь не возражает дать совет по этому поводу? Я пробовал следовать вместе с ответами на StackOverflow Получить уникальное значение одного атрибута из массива ассоциативных массивов , но я теряю $key массива, который является идентификатором сообщения.

1 Ответ

1 голос
/ 12 июля 2020

взгляните на это решение: https://3v4l.org/msUPQ

Я добавил несколько комментариев по коду на случай, если он не ясен:)

Работает, пока как предусмотрено $data упорядочивается по последнему первому (в соответствии со спецификациями).

<?php

declare(strict_types=1);

$data = [
    '-MC1kTfrrDHY3ZbidJ4Q' => [
        'from' => 'lSUfZ4sgEJd',
        'message' => 'test message four no more!',
        'startedAt' => '2020-07-12 11:21:10',
        'to' => 'CWgPqdn3YweN',
    ],
    '-MC09BsjtXP0izITsThf' => [
        'from' => 'CWgPqdn3YweN',
        'message' => 'test message three',
        'startedAt' => '2020-07-11 11:20:19',
        'subject' => '-MC00BHCZlXUp25C5nlS',
        'to' => 'lSUfZ4sgEJd',
    ],
    '-MC1kAi1niswXtjY_h4s' => [
        'from' => 'CWgPqdn3YweN',
        'message' => 'test message two',
        'startedAt' => '2020-07-12 11:19:52',
        'to' => 'lSUfZ4sgEJd',
    ],
    '-MC1kOtfnIlAYtmJsD-a' => [
        'from' => 'CWgPqdn3YweN',
        'message' => 'test message one',
        'startedAt' => '2020-07-12 11:18:50',
        'to' => 'lSUfZ4sgEJd',
    ],
    '-MC1kOtfnIlAhgcufu' => [
        'from' => 'CWgPqdn3YweN',
        'message' => 'test message zero',
        'startedAt' => '2020-07-12 11:00:50',
        'to' => 'YLisXjk07w93',
    ],
];

function getLatestUniqueConversationMessagesByUser(array $message, string $user): array
{
    $conversations = [];
    $latestUniqueConversationMessages = [];
    
    foreach ($message as $messageKey => $message) {
        $participants = [$message['from'], $message['to']];
        
        // Skip entries where $user is has not participated (not sure if needed)
        if (!in_array($user, $participants)) { continue; }
        
        // Make "to|from" same as "from|to"
        sort($participants);
        $conversationKey = join('|', $participants);
        
        // Check if conversation has been handled already
        if (!array_key_exists($conversationKey, $conversations)) {
            $conversations[$conversationKey] = true; // Save as "handled"
            $latestUniqueConversationMessages[$messageKey] = $message; // Save actual data to return
        }
    }
    
    return $latestUniqueConversationMessages;
}

var_dump(getLatestUniqueConversationMessagesByUser($data, 'CWgPqdn3YweN'));

Вывод:

array(2) {
  ["-MC1kTfrrDHY3ZbidJ4Q"]=>
  array(4) {
    ["from"]=>
    string(11) "lSUfZ4sgEJd"
    ["message"]=>
    string(26) "test message four no more!"
    ["startedAt"]=>
    string(19) "2020-07-12 11:21:10"
    ["to"]=>
    string(12) "CWgPqdn3YweN"
  }
  ["-MC1kOtfnIlAhgcufu"]=>
  array(4) {
    ["from"]=>
    string(12) "CWgPqdn3YweN"
    ["message"]=>
    string(17) "test message zero"
    ["startedAt"]=>
    string(19) "2020-07-12 11:00:50"
    ["to"]=>
    string(12) "YLisXjk07w93"
  }
}

Альтернатива с использованием функций массива (не так читаемых):

$messageKeys = 
    array_keys(
        array_unique(
            array_map(
                function ($message) {
                    $participants = [$message['from'], $message['to']];
                    sort($participants);
                    return join('|', $participants);
                },
                $data
            )
        )
    );

var_dump(
    array_filter(
        $data,
        function ($key) use ($messageKeys) {
            return in_array($key, $messageKeys);
        },
        ARRAY_FILTER_USE_KEY
    )
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...