2015-04-16 5 views
3

Учитывая наблюдение за последовательностью исходных объектов, как я могу сопоставить несколько объектов вывода из каждого входного объекта с помощью rxjava? (от одного до большого картографирования)сопоставление от одного до многих с последовательностью наблюдаемых в rxjava

У меня есть список блюд, представляющих предметы, которые составляют заказ ресторана. Мне нужно преобразовать каждое блюдо в одну или несколько OrderLine. Каждая карта Dish создает одну OrderLine для ее названия + цена, по одной OrderLine для каждой Topping и One OrderLine, если у нее есть заметка.

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; 

} 

Есть ли способ сделать это с помощью функционального программирования и/или реактивного программирования?

Я не хочу использовать что-то императив, такие как:


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, ""); 
    } 

} 

вместо этого я хотел бы сделать что-то вроде этого:

Observable.from(dishes).map(/* map each dish to many OrderLine */).

ответ

2

Что вы ищете является flatMap. Это работает с потоком, выводящим другие Observables.

Here's a discussion on map() vs flatMap(), но еще более важно, вот пример (в полной 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) { 
      ... 
     } 
    }); 

Вы, вероятно, хотите, чтобы привлечь функциональность посудомоечных к-OrderLine в другой метод, так что вы можете проверить его, что сделает это намного короче.

Смежные вопросы