簡體   English   中英

迭代並比較地圖中的值 <string, vector<string> &gt; C ++

[英]Iterate and compare values in map<string, vector<string>> c++

我已經使用boost :: filesystem庫在c ++ 17中編寫了一個程序,該程序將路徑作為參數並返回一個映射:

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.重新編寫map方法,或2.遍歷map中的內容,比較該值是否與鍵相關聯,並將此值添加到新的數據結構中。

我不確定哪個會更容易,或者第二個看起來如何,因此不確定是否需要一些建議。

謝謝。


延期:

在創建了文件名-路徑對映射的注釋之后,從上面的舊映射創建了新映射后,我遇到了一個新問題。 我的功能如下:

// 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。

您可以使用boost::bimap而不是std :: map,並同時獲得Dir-> File和File-> Dir查找。

#include <boost/bimap.hpp>
using file_map = boost::bimap<std::string, boost::bimaps::multi_set_of<std::string>>;

然后pathname, filename您將插入pathname, filename對,而不是收集文件名vector與路徑關聯。

請注意,如果僅使用目錄的基本名稱,則可能會重復。 存儲整個路徑,或者multi_set_of在兩側。

您按照注釋中的描述進行嘗試是錯誤的。 它看起來應該像這樣:

std::map<std::string, std::vector<std::string>> 
FinalMap(std::map<std::string, std::vector<std::string>>const& folderToFiles)
{
    std::map<std::string, std::vector<std::string>> fileToFolders;

    for (auto const& pr : folderToFiles)
    {
        for (auto const& file : pr.second)
            fileToFolders[file].push_back(pr.first);
    }

    return fileToFolders;
}

而已。 這枚舉了文件夾到文件的每個映射,並創建了文件到文件夾的新映射。 我很確定,這就是您想要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM