The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

Vincent Hui (6) [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 (104) [Avatar] Offline
#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
        );