这里有两种方法可供使用,它们本质上是相同的思路。我喜欢这些方法,因为它们不包含任何不必要的条件检查或赋值操作。我将第一种方法称为“先打印再处理的方法”。
方法1:先打印再处理的方法
if (!keywords.empty()) {
out << *(keywords.begin());
for (auto it = ++(keywords.begin()); it != keywords.end(); it++)
out << ", " << *it;
}
这是我最初使用的方法。它通过先仅打印容器中的第一个元素,然后在每个后续元素前面加上逗号和空格来工作。它很简单、简洁,并且如果这就是你需要它做的全部事情,那么它非常好用。但是一旦你想要做更多的事情,例如在最后一个元素之前添加 "and",这种方法就显得不够了。你需要检查每次循环迭代是否在最后一个元素上。在列表后添加句点或换行并不是太糟糕。你只需在 for 循环后再添加一行来附加任何你想要的东西。
我更喜欢第二种方法。我称之为“打印最后一个元素的方法”,因为它与第一种方法相同,但顺序相反。
if (!keywords.empty()) {
auto it = keywords.begin(), last = std::prev(keywords.end());
for (; it != last; it++)
out << *it << ", ";
out << "and " << *it << ".\n";
}
这个方法通过打印除最后一个元素外的每个元素,并在其前面添加一个“and”,在其后面添加一个句点,和/或一个换行符,使您可以选择性地处理最后一个元素。正如您所看到的,这种方法为您提供了更多的选项,以便您可以处理最后一个元素,而不会影响循环的性能或添加太多代码。
如果让您不舒服留下for-loop的第一部分为空,您可以这样编写:
if (!keywords.empty()) {
auto it, last;
for (it = keywords.begin(), last = std::prev(keywords.end()); it != last; it++)
out << *it << ", ";
out << "and " << *it << ".\n";
}
for(auto iter = ...;
可以让代码行数更少,但除非你明确打算在循环之后使用它,否则你应该将iter
与循环的作用域绑定。 - user229044