nm92,Nate,Matthews,Aetna,1
sc91,Steve,Combs,Cigna,2
ml94,Morgan,Lands,BCBS,3
kb93,Kyle,Borris,Aetna,2
我正在尝试像上面那样获取CSV输入文件,将其存储,按保险分类(第4列),然后根据保险将其写入diff文件,但按姓氏的字母顺序排列。
因此在此程序中,我有一个uniqueInsurances的向量,而这些向量又有一个注册者的向量。我想以此登记人的名字按姓氏(第3行)按字母顺序排序,因此,如果uniqueInsurances [0] .name是Aetna,则uniqueInsurances [0] .enrollees []的Kyle Borris将列在Nate Matthews之前。现在,我将其存储在Kyle Borris之前列出的Nate Matthews中。
我认为这是由于向量的向量以及此问题所需的嵌套循环的使我感到困惑,所以我想知道是否有人可以帮助指导我针对每个唯一保险对登记者向量进行排序的最佳方式?
struct enrollee
{
string userid = "";
string fname = "";
string lname = "";
string insurance = "";
string version = "";
};
struct uniqueInsurance
{
string name = "";
int numEnrollees = 0;
vector <enrollee> enrollVector;
};
答案 0 :(得分:1)
如果您的任务只是写不同名称的文件,则不需要第二种结构。只需让一个std::vector<enrollee>
根据保险和姓名对其进行排序,然后对其进行迭代。保险名称更改后,请相应地重新打开文件:
std::vector<enrollee> enrollees;
// read them from csv file
std::sort( enrollees.begin(), enrollees.end(), []( const enrollee &e1, const enrollee &e2 ) {
return std::tie( e1.insurance, e1.fname, e1.lname ) < std::tie( e2.insurance, e2.fname, e2.lname );
} );
std::string insurance;
std::ofstream out;
for( const auto &e : enrollees ) {
if( insurance != e.insurance ) {
insurance = e.insurance;
out.open( insurance + ".csv" );
}
out << e.fname << ',' << e.lname << std::endl;
}
这是按照名字然后按姓氏排序的,如果您首先需要姓氏,只需在std::tie()
中交换顺序即可。
答案 1 :(得分:0)
这是昨天您问题的跟进:
我修改了代码,并添加了一行用于排序。
请参阅:
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <regex>
struct Enrollee
{
// Data
std::string userid{};
std::string fname{};
std::string lname{};
std::string insurance{};
std::string version{};
// Overload Extractor Operator to read data from somewhere
friend std::istream& operator >> (std::istream &is, Enrollee& e) {
std::vector<std::string> wordsInLine{}; // Here we will store all words that we read in onle line;
std::string wholeLine; // Temporary storage for the complete line that we will get by getline
std::regex separator("[ \\;\\,]"); ; // Separator for a CSV file
std::getline(is, wholeLine); // Read one complete line and split it into parts
std::copy(std::sregex_token_iterator(wholeLine.begin(), wholeLine.end(), separator, -1), std::sregex_token_iterator(), std::back_inserter(wordsInLine));
// If we have read all expted strings, then store them in our struct
if (wordsInLine.size() == 5) {
e.userid = wordsInLine[0];
e.fname = wordsInLine[1];
e.lname = wordsInLine[2];
e.insurance = wordsInLine[3];
e.version = wordsInLine[4];
}
return is;
}
// Overload Inserter operator. Insert data into output stream
friend std::ostream& operator << (std::ostream& os, const Enrollee& e) {
return os << "userid is: " << e.userid << "\nfname is: " << e.fname << "\nlname is: " << e.lname << "\ninsurance is: " << e.insurance << "\nversion is: " << e.version << '\n';
}
};
int main()
{
// Her we will store all Enrollee data in a dynamic growing vector
std::vector<Enrollee> enrollmentData{};
// Define inputFileStream and open the csv
std::ifstream inputFileStream("r:\\input.csv");
// If we could open the file
if (inputFileStream)
{
// Then read all csv data
std::copy(std::istream_iterator<Enrollee>(inputFileStream), std::istream_iterator<Enrollee>(), std::back_inserter(enrollmentData));
// Sort the data
std:sort(enrollmentData.begin(),enrollmentData.end(),[](const Enrollee& left, const Enrollee& right){return left.lname < right.lname;});
// For Debug Purposes: Print all data to cout
std::copy(enrollmentData.begin(), enrollmentData.end(), std::ostream_iterator<Enrollee>(std::cout, "\n"));
}
else {
std::cerr << "Could not open file 'input.csv'\n";
}
}