Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replicate map, filter and reduce behaviors in C++ using STL?

I suppose we can use std::transform to replicate the map behavior in C++ like this :

std::vector<int> in = { 1 , 2 , 3 ,4 }; 
std::vector<int> out(in.size()); 

std::transform(in.being() , in.end() , out.begin() , [](const int & val)
{
    return val+1;
});

I guess a better way would be to use the back inserter.'

std::vector<int> out2;

std::transform(in.begin() , in.end() , std::back_inserter(out2) , [](const int & val){
      return val + 1;
});

// out will be { 2 , 3 ,4 ,5 }

Am I right ? How do I do the filter and reduce operations in C++ using STL ?

like image 812
nnrales Avatar asked Dec 01 '16 02:12

nnrales


People also ask

What is map filter and reduce?

The functions map(), filter(), and reduce() all do the same thing: They each take a function and a list of elements, and then return the result of applying the function to each element in the list. As previously stated, Python has built-in functions like map(), filter(), and reduce().

Will map reduce and filter work on strings?

Yes, They will all work on strings and any other iterable Data structure.

What does std:: reduce do?

std::reduce. std::accumulate has been a part of the standard library since C++98. It provides a way to fold a binary operation (such as addition) over an iterator range, resulting in a single value. std::reduce was added in C++17 and looks remarkably similar.

What does map function do in C++?

First, a map allows fast access to the value using the key. This property is useful when building any kind of index or reference. Second, the map ensures that a key is unique across the entire data structure, which is an excellent technique for avoiding duplication of data.


2 Answers

You can use std::transform to do mapping, and std::copy_if for filtering.

You have two options for reduce depending on your input and if you want to use a specific type of execution model. I've written some simple examples below to demonstrate common use cases. Note that there are multiple overloads for all these algorithms that you should use depending on your needs.


  1. std::transform

Squaring a vector of integers in place:

std::vector<int> nums{1,2,3,4};
auto unary_op = [](int num) {return std::pow(num, 2);};
std::transform(nums.begin(), nums.end(), nums.begin(), unary_op);
// nums: 1, 4, 9, 16
  1. std::copy_if

Filtering odd numbers only from a vector of integers:

std::vector<int> nums{1,2,3,4};
std::vector<int> odd_nums;
auto pred = [](int num) {return num & 1;};
std::copy_if(nums.begin(), nums.end(), std::back_inserter(odd_nums), pred);
// odd_nums: 1, 3
  1. std::reduce

Sum of integers in the vector starting from 0 using parallel execution model. This is really useful if, for example, you are doing a reduce operation on a really big list. Reckon that the binary operator in this case ("+") is associate and commutative, otherwise the behavior would've been non-deterministic. This is really important. The reduce operation is out-of-order if the execution model is not sequential. Only available since C++17.

std::vector<int> nums{1,2,3,4};
auto binary_op = [](int num1, int num2){return num1 + num2;};
int result = std::reduce(std::execution::par, nums.begin(), nums.end(), 0, binary_op);
// result: 10
  1. std::accumulate

Same as reduce except it doesn't support execution model and the reduce operation is done in-order.

std::vector<int> nums{1,2,3,4};
auto binary_op = [](int num1, int num2){return num1 + num2;};
int result = std::accumulate(nums.begin(), nums.end(), 0, binary_op);
// result: 10
like image 120
happy_sisyphus Avatar answered Oct 14 '22 03:10

happy_sisyphus


Depends which container you use.

std::back_inserter will work only if the container has a push_back function.

For example back_insterter can't be used with forward_list.

In that case we need to have the memory allocated before we call std::transform on the same and first approach is better.

like image 27
Deepak Kr Gupta Avatar answered Oct 14 '22 04:10

Deepak Kr Gupta