J'ai la liste de SourceObjects et j'ai besoin de la convertir en liste de ResultObjects.
Je peux aller d'un objet à un autre en utilisant la méthode de ResultObject:
convertFromSource(srcObj);
bien sûr je peux le faire comme ça:
public void onNext(List<SourceObject> srcObjects) {
List<ResultsObject> resObjects = new ArrayList<>();
for (SourceObject srcObj : srcObjects) {
resObjects.add(new ResultsObject().convertFromSource(srcObj));
}
}
mais je serai très reconnaissant à quelqu'un qui peut montrer comment faire de même avec rxJava .
Si votre Observable
émet une List
, vous pouvez utiliser ces opérateurs:
flatMapIterable
(transformer votre liste en un observable d'éléments)map
(transformer votre article en un autre article) toList
opérateurs (transforme un observable complété en un observable qui émet une liste d'éléments de l'observable terminé)
Observable<SourceObjet> source = ...
source.flatMapIterable(list -> list)
.map(item -> new ResultsObject().convertFromSource(item))
.toList()
.subscribe(transformedList -> ...);
Si vous voulez conserver la Lists
émise par la source Observable
mais convertir le contenu, c'est-à-dire Observable<List<SourceObject>>
en Observable<List<ResultsObject>>
, vous pouvez procéder de la manière suivante:
Observable<List<SourceObject>> source = ...
source.flatMap(list ->
Observable.fromIterable(list)
.map(item -> new ResultsObject().convertFromSource(item))
.toList()
.toObservable() // Required for RxJava 2.x
)
.subscribe(resultsList -> ...);
Cela garantit un certain nombre de choses:
Lists
émis par Observable
est maintenu. c'est-à-dire si la source émet 3 listes, il y aura 3 listes transformées à l'autre boutObservable.fromIterable()
assurera que la Observable
intérieure se termine de sorte que toList()
puisse être utiliséLa méthode Observable.from () factory vous permet de convertir une collection d'objets en un flux Observable. Une fois que vous avez un flux, vous pouvez utiliser l’opérateur map pour transformer chaque élément émis. Enfin, vous devrez vous abonner à l'observable résultant pour pouvoir utiliser les éléments transformés:
// Assuming List<SourceObject> srcObjects
Observable<ResultsObject> resultsObjectObservable = Observable.from(srcObjects).map(new Func1<SourceObject, ResultsObject>() {
@Override
public ResultsObject call(SourceObject srcObj) {
return new ResultsObject().convertFromSource(srcObj);
}
});
resultsObjectObservable.subscribe(new Action1<ResultsObject>() { // at this point is where the transformation will start
@Override
public void call(ResultsObject resultsObject) { // this method will be called after each item has been transformed
// use each transformed item
}
});
La version abrégée si vous utilisez lambdas ressemblerait à ceci:
Observable.from(srcObjects)
.map(srcObj -> new ResultsObject().convertFromSource(srcObj))
.subscribe(resultsObject -> ...);
Ne casse pas la chaîne, juste comme ça.
Observable.from(Arrays.asList(new String[] {"1", "2", "3", }))
.map(s -> Integer.valueOf(s))
.reduce(new ArrayList<Integer>, (list, s) -> {
list.add(s);
return list;
})
.subscribe(i -> {
// Do some thing with 'i', it's a list of Integer.
});
Si vous avez simplement besoin de List<A>
à List<B>
sans manipuler le résultat de List<B>
.
La version la plus propre est:
List<A> a = ... // ["1", "2", ..]
List<B> b = Observable.from(a)
.map(a -> new B(a))
.toList()
.toBlocking()
.single();
En prolongement de Noel excellente réponse. Supposons que la transformation dépende également de certaines données du serveur susceptibles de changer au cours de la souscription. Dans ce cas, utilisez flatMap + scan.
En conséquence, lorsque la liste d'identificateurs est modifiée, les transformations redémarrent. Et lorsque les données du serveur changent en fonction d'un identifiant spécifique, un seul élément est également retransformé.
fun getFarmsWithGroves(): Observable<List<FarmWithGroves>> {
return subscribeForIds() //may change during subscription
.switchMap { idList: Set<String> ->
Observable.fromIterable(idList)
.flatMap { id: String -> transformId(id) } //may change during subscription
.scan(emptyList<FarmWithGroves>()) { collector: List<FarmWithGroves>, candidate: FarmWithGroves ->
updateList(collector, candidate)
}
}
}