Обработка всех элементов на карте на основе нескольких условий - PullRequest
1 голос
/ 14 июля 2020

У меня следующая структура данных:

struct Data
{
    int p1;
    int p2;
    int p3;
    int size;
};

Мне нужно суммировать размер всех элементов в карте на основе параметров p1, p2 и p3. Вот пример кода:

std::unordered_map<int, Data> m;
m[1] = Data{ 11, 22, 33, 10 };
m[2] = Data{ 33, 22, 11, 15 };
m[3] = Data{ 55, 55, 55, 25 };

int p1 = -1, p2 = 22, p3 = -1;
int size = 0;

for(const auto [key, data]: m)
{
    if ((p1 >= 0) && (p2 >= 0) && (p3 >= 0)) 
    {
        if ((p1 == data.p1) && (p2 == data.p2) && (p3 == data.p3))
        {
            size += data.size;
        }
    }
    else if ((p1 >= 0) && (p2 >= 0) && (p3 < 0)) 
    {
        if ((p1 == data.p1) && (p2 == data.p2))
        {
            size += data.size;
        }
    }
    else if ((p1 >= 0) && (p2 < 0) && (p3 >= 0)) 
    {
        if ((p1 == data.p1) && (p3 == data.p3))
        {
            size += data.size;
        }
    }
    else if ((p1 < 0) && (p2 >= 0) && (p3 >= 0)) 
    {
        if ((p2 == data.p2) && (p3 == data.p3))
        {
            size += data.size;
        }
    }
    else if ((p1 < 0) && (p2 < 0) && (p3 >= 0))
    {
        if (p3 == data.p3)
        {
            size += data.size;
        }
    }
    else if ((p1 < 0) && (p2 >= 0) && (p3 < 0)) 
    {
        if (p2 == data.p2)
        {
            size += data.size;
        }
    }
    else if ((p1 >= 0) && (p2 < 0) && (p3 < 0)) 
    {
        if (p1 == data.p1)
        {
            size += data.size;
        }
    }
    else
    {
        size += data.size;
    }
}

Как видите, элементы карты сопоставляются на основе значений p1, p2 и p3. Сумма size равна 25 для указанных выше параметров. Можно ли упростить этот код с помощью функций c ++ 17 / stl?

1 Ответ

0 голосов
/ 14 июля 2020

Если я правильно понимаю, вы можете сильно упростить свой для диапазона l oop следующим образом

   for ( auto const & [key, data] : m )
      if (    ((p1 < 0) || (p1 == data.p1))
           && ((p2 < 0) || (p2 == data.p2))
           && ((p3 < 0) || (p3 == data.p3)) )
         size += data.size;

Если хотите, вы можете использовать std::for_each(), включая <algorithm>

   std::for_each(m.cbegin(), m.cend(), [&](auto const & p)
    { if (    ((p1 < 0) || (p1 == p.second.p1))
           && ((p2 < 0) || (p2 == p.second.p2))
           && ((p3 < 0) || (p3 == p.second.p3)) )
         size += p.second.size; });

, но я не вижу преимуществ перед предыдущим решением.

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