Vincent Hui (3) [Avatar] Offline
#1
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
["apple","mango","noodle","egg","potato"]
The expected output is
["Tom will eat apple and mango","Rose will eat noodle","David will eat egg and potato"]

Thanks
Ivan Cukic (53) [Avatar] Online
#2
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):

    view::zip(
        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
        ),
        foods)

        | 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
        );