Reputation: 12915
Assume
Is it possible at all to process both properties of every user?
The following code is not correct, I know. but how to make it correct? Maybe there are any operators to get it work?
Observable.fromIterable(users)
.map(user -> user.name)
.map(string -> new NameVM(string))
.map(user -> user.age)
.map(int -> new AgeVM(int))
I have only one idea, but I don't like it much
Observable.fromIterable(users)
.doOnNext(user -> new NameVM(string))
.map(user -> user.age)
.map(int -> new AgeVM(int))
Upvotes: 1
Views: 467
Reputation: 12915
I ended up with a container solution
class ContainerVM {
public NameVM nameVM;
public AgeVM ageVM;
}
Observable.fromIterable(users)
.map(user -> buildContainerVM(user));
private ContainerVM buildContainerVM(User user) {
ContainerVM containerVM = new ContainerVM();
containerVM.nameVM = new NameVM(user.name);
containerVM.ageVM = new AgeVM(user.age);
}
Upvotes: 0
Reputation: 4012
You could just process both properties as Singles and zip the result together and flatMap it with flatMapSingle. In doOnNext you would a Container for each zip.
@Test
void name2() throws Exception {
List<User> users =
Arrays.asList(
new User("hans", 30), new User("leon", 66), new User("Uwe", 45), new User("Michi", 23));
Observable<Container> containerObservable =
Observable.fromIterable(users)
.flatMapSingle(
user -> {
Single<ProcessedAge> processedAgeSingle = processeAge(user.age);
Single<ProcessedUserName> processedUserNameSingle =
processeUserName(user.userName);
return Single.zip(
processedAgeSingle,
processedUserNameSingle,
(age, name) -> {
return new Container(age, name);
});
})
.doOnNext(System.out::println);
containerObservable.test().await().assertValueCount(4);
}
private Single<ProcessedAge> processeAge(int age) {
return Single.just(new ProcessedAge());
}
private Single<ProcessedUserName> processeUserName(String userName) {
return Single.just(new ProcessedUserName());
}
class User {
String userName;
int age;
public User(String userName, int age) {
this.userName = userName;
this.age = age;
}
}
class ProcessedUserName {}
class ProcessedAge {}
class Container {
ProcessedUserName userNameResult;
ProcessedAge ageResult;
public Container(ProcessedAge age, ProcessedUserName name) {
this.userNameResult = name;
this.ageResult = age;
}
@Override
public String toString() {
return "Container{" + "userNameResult=" + userNameResult + ", ageResult=" + ageResult + '}';
}
}
Upvotes: 1
Reputation: 2745
I'm not sure what are you trying to do , but from the question I think you have an observable of list of users
and you need to process name
and age
of every user and finally consume the updated user
data. For this why can't you use a single map
operator
Observable.fromIterable(users)
.map(user -> {
user.name =//do something with name);
user.age = // do something with age);
return user;
}).subscribe(user -> {
// here you get the result with processed user object
});
Upvotes: 0