I'm converting some code from Ruby to Scala. Problem is that I never programmed Ruby in my life. It's going well, but now I reached a line that I don't know because I'm new in Scala and I don't understand the sorting mechanism.
So I want to translate this ruby line to scala:
fronts[last_front].sort! {|x,y| crowded_comparison_operator(x,y)}
fronts
is Vector[Vector[Map[String, Any]]]
last_front
is an Int
crowded_comparison_operator(x,y)
returns -1, 0 or 1, x and y are Map[String, Any]
You have two possibilities with standard Scala collections:
- Convert the
-1, 0, 1
output of crowded_comparison_operator
into a boolean that tells you whether the first element is less than the second element, then use sortWith
.
- define a new
Ordering
, pass it explicitly to the sorted
method.
The sortWith
method
The first element is less than the second element if and only if crowded_comparison_operator
returns -1, so you could do this:
fronts(last_front).sortWith{ (x, y) => crowded_comparison_operator(x, y) < 0 }
Defining an Ordering
for sorted
The sorted
method takes an implicit Ordering
parameter. You can define your own custom ordering, and pass it explicitly:
import scala.math.Ordering
fronts(last_front).sorted(new Ordering[Vector[Map[String, Any]]] {
def compare(
x: Vector[Map[String, Any]],
y: Vector[Map[String, Any]]
): Int = crowded_comparison_operator(x, y)
})
or shorter, with scala versions supporting SAM (since 2.11.5, if I remember correctly):
fronts(last_front).sorted(
(x: Vector[Map[String, Any], y: Vector[Map[String, Any]]) =>
crowded_comparison_operator(x, y)
)
Note that, as @mikej has pointed out, Ruby's sort!
sorts the array in-place. This cannot work for an immutable vector, so you have to adjust your code accordingly.