我有SourceObjects列表,我需要将它转换为ResultObjects列表。
我可以使用ResultObject方法将一个对象提取到另一个对象:
--
当然我可以这样做:
convertFromSource(srcObj);
但我会非常感谢能够使用 rxJava 来展示如何做同样事情的人。
答案 0 :(得分:63)
如果Observable
发出List
,您可以使用以下运算符:
flatMapIterable
(将您的列表转换为Observable of items)map
(将您的商品转换为其他商品) toList
运算符(将已完成的Observable转换为Observable,从已完成的Observable中发出项目列表)
Observable<SourceObjet> source = ...
source.flatMapIterable(list -> list)
.map(item -> new ResultsObject().convertFromSource(item))
.toList()
.subscribe(transformedList -> ...);
答案 1 :(得分:48)
如果您想维护来源Lists
发出的Observable
但是将内容转换为Observable<List<SourceObject>>
到Observable<List<ResultsObject>>
,您可以执行以下操作:
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 -> ...);
这确保了以下几点:
Lists
发出的Observable
个数。即如果源发出3个列表,另一端将有3个转换列表Observable.fromIterable()
将确保内部Observable
终止,以便toList()
可以使用答案 2 :(得分:11)
Observable.from()工厂方法允许您将对象集合转换为Observable流。获得流后,您可以使用map运算符转换每个发出的项目。最后,您必须订阅生成的Observable才能使用转换后的项目:
// 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
}
});
如果使用lambdas,缩写版本将如下所示:
Observable.from(srcObjects)
.map(srcObj -> new ResultsObject().convertFromSource(srcObj))
.subscribe(resultsObject -> ...);
答案 3 :(得分:4)
不要破坏链条,就像这样。
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.
});
答案 4 :(得分:1)
使用toList()等待可观察的源代码完成,因此,如果您对一个无限的可观察对象(例如与UI事件和数据库调用绑定的对象)执行此操作,则您的Subscribe()中将永远不会得到任何东西。
解决方案是使用 FlatMapSingle 或 SwitchMapSingle 。
Observable<List<Note>> observable = noteDao.getAllNotes().flatMapSingle(list -> Observable.fromIterable(list).toList());
现在,每次更新列表时,您都可以使该事件的行为可观察到。
答案 5 :(得分:0)
如果你需要的只是List<A>
到List<B>
而不操纵List<B>
的结果。
最干净的版本是:
List<A> a = ... // ["1", "2", ..]
List<B> b = Observable.from(a)
.map(a -> new B(a))
.toList()
.toBlocking()
.single();
答案 6 :(得分:0)
作为Noel好答案的扩展。 假设转换还取决于订阅期间可能更改的某些服务器数据。在这种情况下,请使用 flatMap + 扫描。
当id列表更改时,转换将重新开始。当与特定ID相关的服务器数据更改时,单个项目也将重新转换。
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)
}
}
}
答案 7 :(得分:0)
使用嵌套映射功能进行非阻塞转换
val ints: Observable<List<Int>> = Observable.fromArray(listOf(1, 2, 3))
val strings: Observable<List<String>> = ints.map { list -> list.map { it.toString() } }
答案 8 :(得分:-1)
您可以使用map运算符。例如,如果您有整数列表 s ,并且您想要转换为列表 s 的双打:
List<Integer> li = new ArrayList<>();
Observable.just(li).map( l -> {
List<Double> lr = new ArrayList<Double>();
for(Integer e:l) {
lr.add(e.doubleValue());
}
return lr;
});
但是如果你可以控制observable并将其改为观察单个元素而不是集合,那么所有这一切都更自然。将单个整数元素转换为double整数的相同代码:
Observable.just(1,2,3).map( elem -> elem.doubleValue())