2017-08-21 40 views
0

我正在使用Android室持久性庫,該庫返回MyModel的列表(Flowable<List<MyModel>>)的Flowable列表。 MyModel具有函數getMonth,它返回一個整數。使用RxJava將模型類分組到其他模型

我想將MyModel分組到MyModelWrapper中,MyModelWrapper是MyModel和整數列表(MyModelWrapper(int month, List<MyModel>))的包裝類。

代碼應該組MyModelMyModel(0)MyModel(0)MyModel(1)MyModel(2)列表成MyModelWrapperMyModelWrapper(0, List(MyModel(0), MyModel(0))MyModelWrapper(1, List(MyModel(1))MyModelWrapper(2, List(MyModel(2))列表。我怎麼會RxIfy這裏面沒有使用RxJava

List<MyModel> models = database.myModelDao().getMyModels(); 

Map<Integer, List<MyModel>> orderedData = new HashMap<>(); 
for(MyModel model : models) { 
    if(orderedData.get(model.getMonth()) == null) { 
     orderedData.put(model.getMonth(), new ArrayList<MyModel>()); 
    } 
    orderedData.get(model.getMonth()).add(model); 
} 

final ArrayList<MyModelWrapper> recordedModels = new ArrayList<>(); 
for (Map.Entry<Integer, List<MyModel>> cursor : recordedModels.entrySet()) { 
    List<MyModel> myModelRecords = cursor.getValue(); 
    MyModelWrapper modelWrapper = new MyModelWrapper() 
     .setMyModels(myModelRecords) 
     .setMonth(cursor.getKey()); 
    recordedModels.add(modelWrapper); 
} 

return recordedModels; 

我當前的代碼?

我試圖從Flowablefirst()獲得的第一個元素,在groupBy()我的鑰匙,但被返回GroupedObservable這將在某種程度上變成一個列表,然後轉化爲轉換爲MyModelWrapper列表。

任何幫助表示讚賞!


解決方案我最終使用:

getMyModelsFlowable() 
    .flatMapIterable(new Function<List<MyModel>, Iterable<MyModel>>() { 
     @Override 
     public Iterable<MyModel> apply(List<MyModel> models) throws Exception { 
      return models; 
     } 
    }).groupBy(new Function<MyModel, Integer>() { 
     @Override 
     public Integer apply(MyModel model) throws Exception { 
      return model.getMonth(); 
     } 
    }).flatMapSingle(new Function<GroupedFlowable<Integer, MyModel>, SingleSource<MyModelWrapper>>() { 
     @Override 
     public SingleSource<MyModelWrapper> apply(final GroupedFlowable<Integer, MyModel> group) throws Exception { 
      return group.toList().map(new Function<List<MyModel>, MyModelWrapper>() { 
       @Override 
       public MyModelWrapper apply(List<MyModel> models) throws Exception { 
        return new MyModelWrapper() 
          .setMyModels(models) 
          .setMonth(group.getKey()); 
       } 
      }); 
     } 
    }); 
+0

你可以使用lambda表達式,使其更加簡潔。 – chandil03

回答

2

您的方法與GroupedFlowable是正確的。 考慮這個測試片段

@Test 
fun modelWrap() { 
    val data = Flowable.just(listOf(
      Model(1, "1"), 
      Model(2, "2"), 
      Model(1, "3"), 
      Model(3, "4"))) 
    val modelsByMonth = data.flatMapIterable { it }.groupBy { it.month } 
    val wrappedModels = modelsByMonth 
      .flatMapSingle { group -> 
       group.toList().map { modelsList -> WrappedModel(group.key, modelsList) } 
      } 
    val wrappedModelsList = wrappedModels.toList() 
    val wrappedModelsVal = wrappedModelsList.blockingGet() 
    Assert.assertNotNull(wrappedModelsVal) 
    Assert.assertEquals(3, wrappedModelsVal.size) 

} 

data class Model(val month: Int, val data: String) 
data class WrappedModel(val month: Int?, val data: List<Model>) 

它產生輸出

[WrappedModel(month=1, data=[Model(month=1, data=1), Model(month=1, data=3)]), WrappedModel(month=2, data=[Model(month=2, data=2)]), WrappedModel(month=3, data=[Model(month=3, data=4)])]

我想你是最感興趣wrappedModels VAL是如何構建

+0

示例是用kotlin編寫的 - 確定我看到了有問題的標記。如果有混淆,我會用java重寫它 –

+0

謝謝,這個解決方案的工作原理。我想運營商需要花一些時間習慣/學習... – Empty2k12

0

其中RxJava實現你給出的代碼段的可以做成以下方式:

Single.<List<MyModel>>create(subscriber -> { 
     List<MyModel> models = database.myModelDao().getMyModels(); 
     subscriber.onSuccess(models); 
    }).subscribeOn(Schedulers.io()).map(models -> { 
     Map<Integer, List<MyModel>> orderedData = new HashMap<>(); 
     for(MyModel model : models) { 
      if(orderedData.get(model.getMonth()) == null) { 
       orderedData.put(model.getMonth(), new ArrayList<MyModel>()); 
      } 
      orderedData.get(model.getMonth()).add(model); 
     } 
     final ArrayList<MyModelWrapper> recordedModels = new ArrayList<>(); 
     for (Map.Entry<Integer, List<MyModel>> cursor : recordedModels.entrySet()) { 
      List<MyModel> myModelRecords = cursor.getValue(); 
      MyModelWrapper modelWrapper = new MyModelWrapper() 
        .setMyModels(myModelRecords) 
        .setMonth(cursor.getKey()); 
      recordedModels.add(modelWrapper); 
     } 
     return recordedModels; 
    }).subscribe(recordedModels -> { 
     // this is where you get your converted list 
    }, error -> { 
     // handle exception if any 
    }); 

我不能請參閱您在代碼中提到的任何返回的Flowable。檢查給出的例子,讓我知道它是否有效。

+0

這個答案如何與rx的做事方式有關? –

+0

@ m.ostroverkhov這是我想他想問的。如果你認爲這是不正確的方式,請糾正我。不用客氣。 – chandil03

+0

我認爲OP的目的是爲了避免命令性的樣板代碼(創建列表,迭代它們並手動變換),而是使用一組rx運算符來代替 –