Vincent Hui (6) [Avatar] Offline
In my use case, I need to transform multiple types of inputs in order. I extend the example shown in figure 2.2 in the book to tell the problem I have.
There are 2 types of inputs: 1. a collection of people 2. a collection of foods
and I need to transform inputs to a string that states what a person will eat, male eat 2 foods, female eat 1 food.
Let's say a collection of people is
[{"name":"Tom","sex":"m"}, {"name":"Rose","sex":"f"}, {"name":"David","sex":"m"}]
a collection of foods is
The expected output is
["Tom will eat apple and mango","Rose will eat noodle","David will eat egg and potato"]

Ivan Cukic (97) [Avatar] Offline
The example sounds quite artificial.

You have three options that I see:
- to write it manually (old-school loops or recursion)
- to write a new range transformation by modifying view::zip - to accept two ranges R<T1>, R<T2> and a function T1->int which tells how many items from the second collection to take for each item from the first one
- to abuse ranges something like this (this is not a good solution, but is a nice mental exercise):

        people | view::transform(
            ::: // function that takes a man and returns
                // a vector<optional<person>> with two elements
                // - one man and one empty optional, and if it takes
                // a woman, it returns one element - the woman

        | view::group_by(
           ::: // predicate that returns true if the second item has an
               // empty optional instead of a person

        | view::transform(
           ::: // function that generates the string you need -
               // it gets a group of pair<optional<person>, food>
               // - take the person from the first item in the group,
               // and extract food from all the items