I have a list of restaurants' reservations. I want to group them by day of the year and sort them by time on that day. How can I do so using rxjava?
List reservations;
class Reservation {
public String guestName;
public long time; //time in milliseconds
}
OUTPUT
To do this with RxJava, you could first sort your list by the time (toSortedList
), then perform manual grouping in a flatMap
, outputting an Observable<List<Reservation>>
which gives you each day.
Observable.from(reservations)
.toSortedList(new Func2<Reservation, Reservation, Integer>() {
@Override
public Integer call(Reservation reservation, Reservation reservation2) {
return Long.compare(reservation.time, reservation2.time);
}
})
.flatMap(new Func1<List<Reservation>, Observable<List<Reservation>>>() {
@Override
public Observable<List<Reservation>> call(List<Reservation> reservations) {
List<List<Reservation>> allDays = new ArrayList<>();
List<Reservation> singleDay = new ArrayList<>();
Reservation lastReservation = null;
for (Reservation reservation : reservations) {
if (differentDays(reservation, lastReservation)) {
allDays.add(singleDay);
singleDay = new ArrayList<>();
}
singleDay.add(reservation);
lastReservation = reservation;
}
return Observable.from(allDays);
}
})
.subscribe(new Action1<List<Reservation>>() {
@Override
public void call(List<Reservation> oneDaysReservations) {
// You will get each days reservations, in order, in here to do with as you please.
}
});
The differentDays
method I leave as an exercise for the reader.
Since you already have the complete list of reservations (i.e. a List<Reservation>
, not Observable<Reservation>
), you don't really need RxJava here -- you can do what you need with Java 8 stream/collections API:
Map<Calendar, List<Reservation>> grouped = reservations
.stream()
.collect(Collectors.groupingBy(x -> {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(x.time);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal;
}));
As you can see, all it does is groupingBy
by day of year. If your initial data would use Calendar
instead of long
for the timestamp, this would've looked even simpler, something like:
Map<Calendar, List<Reservation>> grouped = reservations
.stream()
.collect(Collectors.groupingBy(x -> x.time.get(Calendar.DAY_OF_YEAR)));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With