'Reduce custom object using RxJava
I'm using RxJava, I have a list of Point and i want to calculate the distance between each point and get the sum.
The point class look like this
public class Point {
public double x;
public double y;
}
So i need to map and reduce at same time, but i didn't found a solution.
public Observable<Double> totalDistance(Observable<List<Point>> obs) {
return obs.reduceMap(new ArrayList<Integer>, (list, pointA, pointB) -> distance(pointA, pointB)). ?
}
What its the most efficient way to do it (or at least a solution that works) ? Which operator should i use ?
To give a more concrete example, here is what I have and what I want:
Point a (45, 32)
Point b (56, 75)
Point c (44, 53)
Point d (42, 54)
Point e (42, 55)
a to b = 10m
b to c = 15m
c to d = 25m
d to e = 10m
Result = 60m
In reality my points are GPS positions and I use the haversine formula to calculate the distance between two positions.
I use observables because the list of points to be calculated is updated sometime. In fact every x points the user has reached, I have an instruction to send. After sending the instruction, a new list of points until the next instruction is emit.
Solution 1:[1]
You can use the map() method to convert the values of an Observable<List<Point>> to values for an Observable<Double>. The code can look like this:
public static void main(String[] args) throws Exception {
Point a = new Point(45, 32);
Point b = new Point(56, 75);
Point c = new Point(44, 53);
Point d = new Point(42, 54);
Point e = new Point(42, 55);
List<Point> points = new ArrayList<Point>();
points.add(a);
points.add(b);
points.add(c);
points.add(d);
points.add(e);
Subject<List<Point>> subjectOfListOfPoints = PublishSubject.create();
Observable<List<Point>> observable = subjectOfListOfPoints;
Observable<Double> doubleObservable = observable.map(it -> {
return calculateSumOfDistances(it); });
doubleObservable.subscribe(it -> {
System.out.println("The sum is: "+it);
});
subjectOfListOfPoints.onNext(points);
}
private static double calculateSumOfDistances(List<Point> points) {
List<Double> distances = new ArrayList<Double>();
for (int i=0; i<points.size()-1; i++) {
double distance = distance(points.get(i), points.get(i+1));
System.out.println("Distance is: "+distance);
distances.add(distance);
}
double sum = 0;
for (Double d: distances) {
sum += d;
}
return sum;
}
private static double distance(Point a, Point b) {
return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
}
This will create the following output:
Distance is: 44.384682042344295
Distance is: 25.059928172283335
Distance is: 2.23606797749979
Distance is: 1.0
The sum is: 72.68067819212742
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Progman |
