[英]RxJava - convert list and request into map
I have a list of "Parent" objects and I want to get a "Child" list for each of them. 我有一个“父”对象列表,我希望每个对象都有一个“子”列表。 I want as result a map of Parent and Child list.
我想要一个父子列表的地图。 So the result is
结果是
Map<Parent, List<Child>> result = new HashMap<>();
My sample Parent list: 我的示例父列表:
List<Parent> parents = new ArrayList<>();
parents.add(new Parent(1, "Parent1"));
parents.add(new Parent(2, "Parent2"));
parents.add(new Parent(3, "Parent3"));
parents.add(new Parent(4, "Parent4"));
parents.add(new Parent(5, "Parent5"));
I want to iterate them and ask children one by one 我想迭代他们并逐一问孩子们
@GET("api/childs/{parentId}")
Observable<Response<List<Child>>> getChilds(@Path("parentId") int parentId);
What is the best RX structure for this? 什么是最好的RX结构?
Thank you, Robert 谢谢罗伯特
Observable.from(parents)
.concatMap(p -> getChilds(p.getId())
.map(Response::getValue)
.map(children -> Pair.of(p, children)))
.toMap(Pair::getLeft, Pair::getRight)
Where Pair
is a simple wrapper of two value left
and right
. 其中
Pair
是二值的简单包装left
和right
。
The implementation that I thought of is along these lines: 我想到的实现是这样的:
Iterate through the parents, and for each try to form a Map.Entry
with the children by using flatMap()
. 遍历父项,并尝试使用
flatMap()
与子项形成Map.Entry
。 Then you can collect them into a Map
. 然后你可以将它们收集到一张
Map
。 The code looks like this: 代码如下所示:
public static void main(String[] args) {
List<Parent> parents = new ArrayList<>();
parents.add(new Parent(1, "Parent1"));
parents.add(new Parent(2, "Parent2"));
parents.add(new Parent(3, "Parent3"));
parents.add(new Parent(4, "Parent4"));
parents.add(new Parent(5, "Parent5"));
Single<Map<Parent, List<Child>>> result = Observable.fromIterable(parents)
.flatMap(getMapEntries())
.toMap(keySelector(), valueSelector());
}
private static Function<Parent, Observable<Map.Entry<Parent, List<Child>>>> getMapEntries() {
return new Function<Parent, Observable<Map.Entry<Parent, List<Child>>>>() {
@Override
public Observable<Map.Entry<Parent, List<Child>>> apply(Parent parent) throws Exception {
return getChilds(parent.getId())
.map(extractResponse())
.map(createMapEntry(parent));
}
};
}
private static Function<Response<List<Child>>, List<Child>> extractResponse() {
return new Function<Response<List<Child>>, List<Child>>() {
@Override
public List<Child> apply(Response<List<Child>> listResponse) throws Exception {
return listResponse.body();
}
};
}
private static Function<List<Child>, Map.Entry<Parent, List<Child>>> createMapEntry(Parent parent) {
return new Function<List<Child>, Map.Entry<Parent, List<Child>>>() {
@Override
public Map.Entry<Parent, List<Child>> apply(List<Child> children) throws Exception {
return new AbstractMap.SimpleImmutableEntry<>(parent, children);
}
};
}
private static Function<Map.Entry<Parent, List<Child>>, Parent> keySelector() {
return new Function<Map.Entry<Parent, List<Child>>, Parent>() {
@Override
public Parent apply(Map.Entry<Parent, List<Child>> parentListEntry) throws Exception {
return parentListEntry.getKey();
}
};
}
private static Function<Map.Entry<Parent, List<Child>>, List<Child>> valueSelector() {
return new Function<Map.Entry<Parent, List<Child>>, List<Child>>() {
@Override
public List<Child> apply(Map.Entry<Parent, List<Child>> parentListEntry) throws Exception {
return parentListEntry.getValue();
}
};
}
However, you should also handle errors for your Response
. 但是,您还应该处理
Response
错误。 You can do it in extractResponse()
, by throwing an exception for instance. 您可以通过抛出异常来在
extractResponse()
执行此操作。
Btw, the plural for child
is children
. 顺便说一句,
child
的复数是children
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.