Home > Software design >  Can you access the current iterator from a function used by the transform function in c ?
Can you access the current iterator from a function used by the transform function in c ?

Time:10-19

Can you access the current iterator from a function used by the transform function in c so that you can reference previous and latter values? I want to use the transform function to iterate through a vector, performing operations on the vector that rely on values before and after the current value.

For example, say I have a vector with values [1,2,4,3,5,6], and I want to start at the second value, and iterate until the second to last value. On each of those elements, I want to make a new value that equals the sum of the value, and the values next to it in the original. The ending vector would look like [7,9,12,14].

auto originalsBeginIterator = originalPoints.begin();
auto originalsEndIterator = originalPoints.end();
std::advance(originalsBeginIterator, 1);
std::advance(originalsEndIterator,-1);
std::transform(originalsBeginIterator,originalsEndIterator,alteredValues.begin(),
[](int x) x = { return {previous value}   x   {next value};} 
);

Is there any way to reference previous and latter values from the original array when using transform?

CodePudding user response:

Clearly the tool std::transform simply doesn't give you a way to do that: it either takes a unary predicate to be applied to individual elements of of one collection, or a binary predicate to be applied to corresponding elements of two collections.

But the point is that, from the functional programming perspective, what you are trying to do is simply not a transform.

How can you go about it instead? You could zip that vector, let's call it v, the same vector deprived of its first element, and the same vector deprived from its second element; you would then sum the 3 elements of each pair.

Range-v3 gives you a way to do this quite tersely:

#include <iostream>
#include <range/v3/view/drop.hpp>
#include <range/v3/view/transform.hpp>
#include <range/v3/view/zip_with.hpp>
#include <vector>

using namespace ranges::views;
int main()
{
    // input
    std::vector<int> v{1,2,3,4,5,6};

    // to sum 3 ints
    auto constexpr plus = [](int x, int y, int z){ return x   y   z; };

    // one-liner
    auto w = zip_with(plus, v, v | drop(1), v | drop(2));

    // output
    std::cout << w << std::endl;
}

v | drop(1) gives you a view on the elements {2,3,4,5,6}, and v | drop(2) on {3,4,5,6}; zip_with taks a n-ary function and n ranges and combines the n-tuple of corresponding elements from the n ranges using the n-ary function. So in our case it'll go like this:

v                         = {1, 2, 3, 4, 5, 6}
                                       
v1 = v | drop(1)          = {2, 3, 4, 5, 6}
                                       
v2 = v | drop(2)          = {3, 4, 5, 6}
zip_with(plus, v, v1, v2) = {6, 9,12,15} 
  • Related