Является ли лучший способ получить среднее значение ключа unordered_multimap?
Я ищу получить все значение одного ключа в моем unordered_multimap, который на самом деле складывает int и значение, представляющее время выполнения в наносекундах. Мне нужно получить все значение, чтобы заменить несколько ключей одним ключом со средним значением.
Я пробовал код, на самом деле это самый ценный:
std::unordered_multimap<int, std::chrono::nanoseconds> data;
std::chrono::nanoseconds average;
// *filling my map with value*
for (auto & pair : data){
auto range = data.equal_range(pair.first);
for_each (
range.first,
range.second,
[](std::unordered_multimap<int, std::chrono::nanoseconds>::value_type& x){
average = average + x.second;
}
);
average = average / data.count(pair.first);
data.erase(pair.first);
data.insert({pair.first, average});
}
Ошибка, которую я получаю error: 'average' is not captured : average = average + x.second;
1 ответ
Решение
Скорее, чем std::for_each
, используйте std::accumulate
.
Обратите внимание, что удаление записей из std::unordered_multimap
в пределах диапазона это неопределенное поведение. Безопаснее наполнить другую емкость.
std::unordered_multimap<int, std::chrono::nanoseconds> data;
// *filling my map with value*
std::unordered_multimap<int, std::chrono::nanoseconds> new_data;
for (auto it = data.begin(); it != data.end(); ++it){
auto range = data.equal_range(it->first);
auto average = std::accumulate (
range.first,
range.second,
std::chrono::nanoseconds{0},
[](auto sum, auto & x){
return sum + x.second;
}
) / std::distance(range.first, range.second);
new_data.emplace(key, average);
}
data.swap(new_data);
В качестве альтернативы, если у вас есть C++17, std::transform_reduce
.
std::transform_reduce(
range.first,
range.second,
std::chrono::nanoseconds{0},
std::plus<>{},
[](auto & x) { return x.second; }
)