Given an Observable of a sequence of source objects, how can I map multiple output Objects out of each input object using rxjava? (one to many mapping)
I have a list of dishes representing the items that compose an order of a restaurant. I need to transform each Dish into one or more OrderLine. Each Dish map creates one OrderLine for its name+price, one OrderLine for each Topping and one OrderLine if it has a note.
INPUT
List dishes = {...}
OUTPUT
List orderLines = {...}
class Dish {
public String name;
public List toppings;
public String note;
public BigDecimal price;
}
class Topping {
public String name;
public BigDecimal price;
}
class OrderLine {
public String name;
public BigDecimal price;
}
Is there a way to do so using Functional Programming and/or Reactive Programming?
I do not want to use something imperative such as:
List orderLines = new ArrayList();
for (Dish dish : dishes) {
orderLines.add(new OrderLine(dish.name, dish.price);
for (Topping topping : dish.toppings) {
orderLines.add(new OrderLine(topping.name, topping.price);
}
if(note != null) {
orderLines.add(new OrderLine(dish.note, "");
}
}
instead I would like to do something like this:
Observable.from(dishes).map( /* map each dish to many OrderLine */ ).
What you're looking for is flatMap
. This operates on a stream, outputting other Observables.
Here's a discussion on map()
vs flatMap()
, but even more importantly here's an example (in full Java 7):
Observable.from(dishes)
.flatMap(new Func1<Dish, Observable<OrderLine>>() {
@Override
public Observable<OrderLine> call(Dish dish) {
List<OrderLine> orderLines = new ArrayList<>();
orderLines.add(new OrderLine(dish.name, dish.price);
for (Topping topping : dish.toppings) {
orderLines.add(new OrderLine(topping.name, topping.price);
}
if(dish.note != null) {
orderLines.add(new OrderLine(dish.note, "");
}
return Observable.from(orderLines);
}
})
.subscribe(new Action1<OrderLine>() {
@Override
public void call(OrderLine orderLine) {
...
}
});
You probably want to draw the Dish-to-OrderLine functionality out into another method so you can test it, which would make this much briefer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With