1

I am trying to perform averages on some values in a vector of pairs that have the same first element, and then storing it inside of a map. For example:

std::vector<std::pair<int, double>> test;
test.push_back(std::make_pair(1,100.0));
test.push_back(std::make_pair(1,200.0));
test.push_back(std::make_pair(1,400.0));
test.push_back(std::make_pair(2,200.0));
test.push_back(std::make_pair(2,300.0));
test.push_back(std::make_pair(3,100.0));

std::map<int, double> test2;
test2 would then contain: {{1, 233.33}, {2, 250}, {3, 100}};

The issue I am having is finding all the duplicate first elements then performing the average.

Note: the test vector is sorted using the code below:

std::sort(test.begin(), test.end(), 
     [](auto a, auto b) 
     {          
         return a.first < b.first;       
     });

Can someone explain how I should go about doing this?

Job_September_2020
  • 858
  • 2
  • 10
  • 25
pennyBoy
  • 397
  • 2
  • 17
  • Is it pure coincidence the vector in your example is already sorted by obj.first ? – WhozCraig Jun 22 '21 at 21:45
  • 2
    First sort the vector by the first element and then iterate over it and calculate the average value. Of course, if it's already sorted you don't need to do it. –  Jun 22 '21 at 21:45
  • @WhozCraig it's not already sorted. – pennyBoy Jun 22 '21 at 22:15
  • My approach: Use a [range-based for loop](https://en.cppreference.com/w/cpp/language/range-for) to iterate over the vector and sum up all values with same first element. After the first element changes reset the sum, the counter and store the value in a map. –  Jun 22 '21 at 22:32
  • Related: [Calculate rolling / moving average in C++](https://stackoverflow.com/questions/10990618/) – Remy Lebeau Jun 22 '21 at 22:35
  • Notice that regular comparison would do the job too. – Jarod42 Jun 23 '21 at 08:08

1 Answers1

1

Assuming you have your vector sorted sequentially by the first pair element you can do something like:

double sum {0.0};
int count {0};
int key {pair[0].first};

for (auto pair : vec) {
  if (pair.first != key) {
    map.insert(key, sum / count);
    key = pair;
    sum = 0.0;
    count = 0;
  }
  sum += pair.second;
  count++;
}

if (count > 0) {
  map.insert(key, sum / count);
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
Josh Hardman
  • 721
  • 6
  • 17
  • Nice, If there were only two entries with the same key, the if statement never becomes true, how do I check whether they key is the last element in the map? – pennyBoy Jun 23 '21 at 00:19
  • Check the count (incase vec was empty) then insert then final entry. – Josh Hardman Jun 23 '21 at 00:39