如何将2列CSV文件读取为具有范围的映射?



我得到了一个每行有两个元素的CSV文件:

1,2
12,40
11,7
...

我想把它读入std::map<int, int>

我怎么能做到这一点,使用任何从范围库和范围v3?

在这个答案的帮助下,我现在得到的是:

#include <boost/hof/lift.hpp>
#include <iostream>
#include <range/v3/istream_range.hpp>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/istream.hpp>
#include <range/v3/view/join.hpp>
#include <range/v3/view/chunk.hpp>
#include <range/v3/view/transform.hpp>
#include <range/v3/view/split.hpp>
#include <string>
using ranges::istream;
using ranges::to;
using namespace ranges::views;
constexpr auto splitAtComma = [](auto const& r) { return r | split(','); };
constexpr auto rngToString = [](auto const& r) { return r | to<std::string>; };
constexpr auto strToInt = BOOST_HOF_LIFT(std::stoi);
constexpr auto parseCoords = transform(splitAtComma)
| join
| transform(rngToString)
| transform(strToInt)
| chunk(2);
int main() {
auto lines = istream<std::string>(std::cin);
auto coords = lines | parseCoords;
std::cout << coords << std::endl;
}

,像这样调用

./main <<END
1,2
12,40
11,7
END

给出如下输出

[[1,2],[12,40],[11,7]]

关键是现在我不知道如何将range-of-ranges转换成映射。此外,我有一种感觉,我在一条死胡同里,因为std::map<int, int>的每个元素都来自2个ints,但在[1,2],[12,40][11,7]以上的范围中,范围只是ints的范围,而不是在编译时编码,只有2个ints。

这里不需要使用join,因为r | split(',')已经为您提供了包含两个元素的范围。std::from_chars优于std::stoi

你只能使用标准库的<ranges>

#include <ranges>
#include <charconv>
#include <fmt/ranges.h>
#include <sstream>
auto toInt = [](auto r) {
int i = 0;
std::from_chars(std::to_address(r.begin()), std::to_address(r.end()), i);
return i;
};
auto parseCoords = 
std::views::transform(
[](auto r) { return std::move(r) | std::views::split(','); })
| std::views::transform(
[](auto r) { return std::pair{toInt(r.front()), toInt(*++r.begin())}; });
int main() {
auto in = std::istringstream{R"(
1,2
12,40
11,7
)"};
auto coords = std::views::istream<std::string>(in)
| parseCoords;
fmt::print("{}n", coords);
}

演示注意views::transform中的std::move(r)是必要的,因为我们需要构造一个owning_view来避免悬空问题。

相关内容

  • 没有找到相关文章

最新更新