'Get first N elements of std::list?
What is the correct and safe way to get a new list that is the first N elements of a std::list or the entire list if N >= the list size (and handles N = 0 as well)?
Update
In fact I don't necessarily need a new list, I just want to operate on the subset of the list in subsequent code. I assume creating a new list is a reasonable way to do this (note list size will typically be under 50).
Solution 1:[1]
std::list<int> a;
size_t n = 13;
auto end = std::next(a.begin(), std::min(n, a.size()));
Make a new list containing the first n elements of the first list:
std::list<int> b(a.begin(), end);
Or populate an existing list:
std::list<int> b;
std::copy(a.begin(), end, std::back_inserter(b));
Solution 2:[2]
template<typename T>
std::list<T> first_n(const std::list<T> &in, std::size_t n) {
return std::list<T> out{in.begin(),
std::next(in.begin(), std::min(in.size(), n))};
}
Solution 3:[3]
// list<int> input;
list<int> output;
for (list<int>::const_iterator i = input.begin(); i != input.end() && N > 0; ++i, --N)
output.push_back(*i);
Solution 4:[4]
In your question noticed saying
In fact I don't necessarily need a new list, I just want to operate on the subset of the list in subsequent code
Form C++17 one can use std::for_each_n
For example lets square the first N (4) numbers in the list.
Example 1 : Modify in place :
std::list<int> nums{ 1,2,3,4,5,6,7,8 };
//MAKE NOTE OF SENDING ARGUMENT AS A REFERENCE (int& num)
std::for_each_n(nums.begin(), 4, [](int& num) { num = num * num; });
//PRINT
for (auto n : nums)
std::cout << n << " ";
Example 2 : Modify and put them in a different list :
std::list<int> nums2{ 1,2,3,4,5,6,7,8 };
std::list<int> newNums;
//MAKE NOTE OF CAPTURE [&}, newNums EXPOSED INSIDE LAMBDA.
std::for_each_n(nums2.begin(), 4, [&](int num) {newNums.push_back(num * num); });
//PRINT
for (auto n : newNums)
std::cout << n << " ";
Also there is an overload available to specify execution policy, Need to include "execution" header. So the below code executes with parallel execution policy, useful for parallel processing lists huge in size.
std::for_each_n(std::execution::par,nums.begin(), 4, [](int& num) { num = num * num; });
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | ecatmur |
| Solution 3 | timrau |
| Solution 4 | Pavan Chandaka |
