По сути, я хочу сгруппировать элементы мультикарты по ключу и получить новую структуру данных в виде карты.
мультикарта:
std::multimap<std::string,std::vector<int>> multiMap;
VecA VecB
ABC 10 30
ABC 10 30
DEF 20 20
требуемый вывод:
std::map<std::string,std::vector<int>> map;
VecA VecB
ABC 20 60
DEF 20 20
Следующий код работает для std::multimap<std::string,int>
std::vector<std::string> a = {ABC,ABC,DEF,GHI};
std::vector<int> b = {10,20,30,40};
std::multimap<std::string,int> multiMap;
for (int i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,int >(a[i], b[i]));
}
std::map<std::string,int> map;
std::for_each
(
multiMap.begin(),
multiMap.end(),
[&map] (auto const & i)
{
map[i.first] += i.second;
}
);
Я не могу изменить код в строке 19 вышеприведенного блока (т.е. в лямбда-функции), чтобы расширить в случае std::multimap<std::string,std::vector<int>>
до std::map<std::string,std::vector<int>>
Если ответ поможет, не стесняйтесь проголосовать за него :)
Используйте valarray
Демо: https://wandbox.org/permlink/SAnHNKNZ0UufqZsN
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <valarray>
#include <numeric>
int main()
{
using key_type = std::valarray<int>;
key_type b = {10,20,30,40};
auto containerToStr = [](const auto& cont)
{
return std::accumulate(std::begin(cont), std::end(cont), std::string{}, [](const auto& str, const auto& val){
return str + " " + std::to_string(val);
});
};
std::multimap<std::string,key_type> multiMap;
std::vector<std::string> a = {"ABC","ABC","DEF","GHI"};
for (size_t i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,key_type >(a[i], b));
}
std::cout << "Before sum" << std::endl;
for (const auto& p : multiMap)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
std::cout << std::endl;
std::map<std::string,key_type> map;
std::for_each( multiMap.begin(), multiMap.end(), [&map] (auto const & i)
{
// map[i.first] += i.second; // caution map[i.first] create an empty key_type
if ( map.count(i.first) > 0)
{
map.at(i.first) += i.second;
}
else
{
map.insert({i.first, i.second});
}
}
);
std::cout << "After sum" << std::endl;
for (const auto& p : map)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
}
std::vector
Определите свою функцию суммы.
Демо: https://wandbox.org/permlink/FteFkLfwQh0P4wzp
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <numeric>
int main()
{
using key_type = std::vector<int>;
key_type b = {10,20,30,40};
auto containerToStr = [](const auto& cont)
{
return std::accumulate(std::begin(cont), std::end(cont), std::string{}, [](const auto& str, const auto& val){
return str + " " + std::to_string(val);
});
};
std::multimap<std::string,key_type> multiMap;
std::vector<std::string> a = {"ABC","ABC","DEF","GHI"};
for (size_t i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,key_type >(a[i], b));
}
std::cout << "Before sum" << std::endl;
for (const auto& p : multiMap)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
std::cout << std::endl;
std::map<std::string,key_type> map;
// Warning : naive function, to rework
auto your_sum = [](const auto& cont1, const auto& cont2)
{
key_type result;
const auto smaller = std::min(cont1.size(), cont2.size());
for ( size_t i = 0 ; i < smaller; i++)
{
result.push_back(cont1[i]+cont2[i]);
}
return result;
};
std::for_each( multiMap.begin(), multiMap.end(), [&map,&your_sum] (auto const & i)
{
// map[i.first] += i.second; // caution map[i.first] create an empty key_type
if ( map.count(i.first) > 0)
{
map.at(i.first) = your_sum(i.second, map.at(i.first));
}
else
{
map.insert({i.first, i.second});
}
}
);
std::cout << "After sum" << std::endl;
for (const auto& p : map)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
}
может быть что-то вроде
map[i.first] = my_sum_fucntion(i.second, map[i.first]);
? Вы должны определить, как вы хотите суммировать два вектора.