我尝试使用StackOverFlow API。我希望标记列表包含名称,计数和描述。问题是描述以不同的api函数返回:
https://api.stackexchange.com/2.2/tags?page=1&pagesize=3&order=desc&sort=popular&site=stackoverflow
只给出了3个所需字段中的两个:(通过点击链接尝试:)
https://api.stackexchange.com/2.2/tags/javascript%3Bjava%3Bc%23/wikis?site=stackoverflow 取标签名称并给我:
我构建了一个Retrofit界面:
class Item {
@SerializedName("name")
public String name;
@SerializedName("count")
public String count;
@SerializedName("excerpt")
public String excerpt;
}
class Items {
@SerializedName("items")
public Item[] items;
}
@GET("/2.2/tags")
Observable<Items> getItems(@Query("page") String page,
@Query("pagesize") String pagesize,
@Query("order") String order,
@Query("sort") String sort,
@Query("site") String site);
@GET("/2.2/tags/{tagnames}/wikis")
Observable<Items> getDescription(@Path("tagnames") String tagnames,
@Query("site") String site);
所以,首先,我们应该执行getItems,然后获取所有名称并执行getDescription func,最后使用新字段来填充我们的Items。 所以我想收集所有3个(一个可观察的名称,计数和摘录)。
到目前为止,这是我的观察者:
App.getServerAPI()
.getItems("page", "pagesize", "order","sort", "site") //just example strings
.observeOn(AndroidSchedulers.mainThread());
我应该怎么做?我应该在两个函数中使用Observable吗?
更新: 按照你的建议我到目前为止写了一个:
public Observable<ServerAPI.Tags> call() {
return App.getServerAPI()
.getItems("page", "pagesize", "order", "sort", "site")
.map(new Func1<ServerAPI.Tags, ServerAPI.Tags>() {
@Override
public ServerAPI.Tags call(ServerAPI.Tags tags) {
String tagsStr = "";
for (ServerAPI.Tag tag: tags.items){
tagsStr +=tag.name+";";
}
ServerAPI.Excerts excerts = App.getServerAPI().
getExcerts(tagsStr, "site");
for (ServerAPI.Excert excertItem : excerts.items){
for (ServerAPI.Tag tagItem: tags.items){
if (excertItem.tag_name.equals(tagItem.name)){
tagItem.excerpt = excertItem.excerpt;
}
}
}
return tags;
}
})
.delay(1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread());
}
看起来很难看!
答案 0 :(得分:1)
我会这样做:
Object
<强>更新强>
以下是为标签列表调用Api的示例。
class Tag{
public String name;
public String count;
}
class TagList {
public List<Tag> tags;
}
class Excert {
public String excert;
}
class Item {
public final String name;
public final String count;
public final String excert;
public Item(String name, String count, String excert) {
this.name = name;
this.count = count;
this.excert = excert;
}
}
Observable<TagList> getItems() {}
Observable<Excert> getExcert(String tagName) {}
public void testFlatMap() {
getItems()
//iterate over each Tag
.flatMap(tagList -> Observable.from(tagList.tags))
//call server for excert
.flatMap(tag -> getExcert(tag.name),
new Func2<Tag, Excert, Item>() {
@Override
public Item call(Tag tag, Excert excert) {
//compose final data structure
return new Item(tag.name, tag.count, excert.excert);
}
})
//item here
.subscribe(item -> {
});
}
答案 1 :(得分:0)
您可以更改getDescription
方法:
Observable<Items> getDescription(@Path("tagnames") String tagnames,
@Query("site") String site);
到
DescriptionResponse getDescription(@Path("tagnames") String tagnames,
@Query("site") String site);
其中DescriptionResponse
表示响应对象:
public class DescriptionResponse {
List<DescriptionItem> items;
}
然后获取商品并使用map
运算符获取说明并将其映射到您的商品:
api.getItems("", "", "", "", "").map(items -> {
String tags = "";//iterate over items and grab all tags
DescriptionResponse description = api.getDescription(tags, "");
//iterate over items and descriptions in response and set appropriate description
return items;
}).subscribe(items -> {
//here is your items with descriptions
});