Я написал программу на c ++ 17 с использованием библиотеки boost :: filesystem, которая принимает путь в качестве аргумента и возвращает карту:
map<string, vector<string>>
, где каждый ключ является каталогом (boost:: filesystem :: path преобразуется в строку), и каждый файл в каждом каталоге помещается в вектор значений.
Сначала я создаю вектор путей из пути, заданного в качестве аргумента:
// Method to create vector of paths
vector<path> InToVecsOne(path p, vector<path> v1)
{
for(auto entry : recursive_directory_iterator(p))
{
if(is_directory(entry))
{
v1.push_back(entry);
}
}
return v1;
}
Затем я создаю карту, используя вектор следующим образом:
// Function takes a vector of paths and returns map of key-value pair path-vector<string>
map<string,vector<string>> FileMap(vector<path> v1,
map<string,vector<string>> m, vector<string> v2)
{
for(auto p : v1)
{
// iterate over each entry in path p
for(auto entry : directory_iterator(p))
{
if(is_regular_file(entry) == true)
{
// add file to vector<string>
v2.push_back(basename(entry) + " ");
}
}
// convert path to pathname (DirX) string
string pathname = basename(p);
m.insert(make_pair(pathname, v2));
v2.erase(v2.begin(), v2.end()); // remove contents after iterating
}
return m;
}
Используя мою папку с песочницей в качестве тестового пути, я получаю следующий вывод при печати содержимого моей карты:
DirA: Z X Y
DirB: Z X Y
DirBB: X Y YY
DirC: Z
DirCC: ZZ X Y YY
Как заметно, ключи - DirA, DirB, DirBB и т. Д., А также значенияZ, X, Y и т. д.
Теперь я хочу преобразовать вещи так, чтобы мой вывод выглядел следующим образом:
X : DirA, DirB, DirBB, DirCC
Y : DirA, DirB, DirBB, DirCC
и т. д.
Я думаю, что лучшим способом для этого было бы: 1. переписать метод карты или 2. перебрать содержимое карты, сравнить, если значение связано с ключом, и добавить этозначение для новой структуры данных.
Я не уверен, что будет проще, или как будет выглядеть второй, и, следовательно, потребуется какой-то совет.
Спасибо.
Расширение:
Следуя комментарию, чтобы создать карту пар имя-путь-путь, я столкнулся с новой проблемой после создания этой новой карты из старойкарта выше.Моя функция выглядит следующим образом:
// Make new map where file is key, and dir is value. m1 is old map, m2 is new map
map<string,vector<string>> FinalMap(map<string,vector<string>> m1,
map<string,vector<string>> m2, vector<string> dirnames)
{
// iterate over each key
for(map<string,vector<string>>::const_iterator it = m1.begin(); it != m1.end(); ++it)
{
string dirname = it->first;
dirnames.push_back(dirname);
vector<string> files = it->second;
// iterate over elements in vector<string> files
for(auto i : files)
{
m2.insert(make_pair(i, dirnames));
}
dirnames.erase(dirnames.begin(), dirnames.end());
}
return m2;
}
Однако теперь мой вывод выглядит следующим образом:
X : DirA
Y : DirA
YY : DirBB
Z : DirA
ZZ : DirCC
Мне нужно, чтобы оно было:
X : DirA, DirB, DirBB
и т. Д.учитывая, что файл X находится в DirA, DirB и DirBB.Поэтому я должен изменить функцию FileMap.