簡體   English   中英

如何使用鍵向量從 map 過濾值並使用 c++ 范圍語法生成集合

[英]how to use a vector of keys to filter values from a map and produce a set using c++ ranges syntax

我是Eric Niebler 的 range-v3 庫的新手,我想解決以下簡單問題:

我有一個std::map包含以下內容:

std::map<std::string, int> map = {
    {"THIS", 1}, {"IS", 2}, {"A", 3}, {"TEST", 4}, {"WITH", 5}, {"MORE", 6}, {"KEYS", 7}
};

我有一個std::vector包含一組鍵,如下所示:

std::vector<std::string> vec = {
    "THIS", "IS", "A", "TEST" 
};

如何使用庫(理想情況下使用 pipe 組合語法)從包含向量中的鍵的 map 中過濾掉對,並將結果視圖轉碼為std::set<std::pair<std::string, int>> . 此外,為了使轉碼有趣,請確保 map 中的值必須是奇數。 在這種情況下,范圍代碼應該:

使用這些鍵:

THIS,IS,A,TEST,

針對這個 map

{A,3},{IS,2},{KEYS,7},{MORE,6},{TEST,4},{THIS,1},{WITH,5},

具有奇數 map 值謂詞 - 產生以下結果作為不同類型的容器std::set

{A,3},{THIS,1},

這應該相對簡單,但我無法弄清楚新語法。 此外,任何關於渴望與懶惰的見解都將有助於我理解。

以下精簡的coliru示例顯示了我正在尋找的內容。

您是否正在尋找這樣的東西:


    std::map<std::string, int> map = {{"THIS", 1}, {"IS", 2},   {"A", 3},   {"TEST", 4},
                                      {"WITH", 5}, {"MORE", 6}, {"KEYS", 7}};

    std::vector<std::string> keys = {"THIS", "IS", "A", "TEST"};

    auto output = map | ranges::views::filter([&](auto &&pair) {
                      return std::find(keys.begin(), keys.end(), pair.first) != keys.end() && pair.second % 2 == 1;
                  });

    std::set<std::pair<std::string, int>> set(output.begin(), output.end());

    for (auto [key, value] : set) std::cout << key << " " << value << std::endl;

在這里,我用向量過濾了 map 並創建了一個range adaptor closure object 然后我從 output 創建了一個集合。

關於懶惰,看這段代碼:


    std::map<std::string, int> map = {{"THIS", 1}, {"IS", 2},   {"A", 3},   {"TEST", 4},
                                      {"WITH", 5}, {"MORE", 6}, {"KEYS", 7}};

    std::vector<std::string> keys = {"THIS", "IS", "A", "TEST"};

    auto output = map | ranges::views::filter([&](auto &&pair) {
                      std::cout << "Seen" << std::endl;
                      return std::find(keys.begin(), keys.end(), pair.first) != keys.end() && pair.second % 2 == 1;
                  });

    std::cout << "I'm lazy!" << std::endl;

    std::set<std::pair<std::string, int>> set(output.begin(), output.end());

    for (auto [key, value] : set) std::cout << key << " " << value << std::endl;

我添加了一些印刷品。 output 是:

I'm lazy!
Seen
Seen
Seen
Seen
Seen
Seen
Seen
A 3
THIS 1

這表明在使用output創建集合之前,不會評估output

與遍歷整個map相比, map vec搜索操作是第 logarith

std::set<std::pair<std::string, int>> set;
std::ranges::copy(
  vec | std::views::transform([&map](auto& key) { return map.find(key); })
      | std::views::filter([&map](auto it) { return it != map.end() && 
                                                    it->second % 2 == 1; })
      | std::views::transform([](auto it) { return *it; }),
  std::inserter(set, set.begin()));

演示

暫無
暫無

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

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