I've got a file structured like this:
A 123456 0
G 123456 5
A 235334 0
B 123456 2
Each piece of information is being stored like so:
temp.code >> temp.personid >> temp.data
I've stored this information in a Vector
ifstream fin("test.txt");
vector<TestClass> test;
TestClass temp;
string line;
while (getline(fin, line)) {//.. test.push_back(temp);}
A given personid can come up numerous times within the file. What I want to do is iterate through the vector and group the repetitions into a single class object per personid, my goal is that I want sum the data for each particular object such that the output for the file above would be:
123456 : 7
235334 : 0
What would be an elegant way to approach this?
Thanks
The following code uses an std::unordered_map
as suggested by the comments already. It will read your file line by line.
The code assumes that the person's id is of type int
, the code of type std::string
and the data of type int
.
It inserts every Person
(here as example a struct) into the map. If a person's id is already there it will sum up the data. That means that this solution doesn't use a temporary std::vector
but only the std::unordered_map
.
See live example with your data on ideone.com.
Code:
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <unordered_map>
struct Person
{
std::string code;
int data;
};
typedef std::unordered_map<int, Person> PersonMap;
int main()
{
std::ifstream fin("test.txt");
PersonMap persons;
/* line by line reading */
for (std::string line; std::getline(fin, line); )
{
std::istringstream iss(line);
int personId;
Person personData;
/* parse line as std::string, int, int */
iss >> personData.code >> personId >> personData.data;
/* insert into map and save result */
std::pair<PersonMap::iterator, bool> insertResult =
persons.insert(std::pair<int, Person>(personId, personData));
/* if personId is already there */
if (!insertResult.second)
{
insertResult.first->second.data += personData.data;
}
}
/* output whole map */
for(auto const &person : persons)
{
std::cout << person.first << " : " << person.second.data << "\n";
}
std::cout << std::flush;
}
Output:
235334 : 0 123456 : 7
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With