Eradicator_1729
Eradicator_1729

Reputation: 180

Finding max (& min) among values of specific index in a series of arrays that are the values of a map

I have a data structure defined in the following way: An array of maps where each map has String keys and Arrays of Doubles as values. i.e. Array [Map [String, Array [Double]]]

The reasoning behind this structure is that each String key is an identifier of a highway, with the values representing the lats and longs of traffic sensors along the highway. I have multiple highways so the need for multiple maps. What I need to do now is find the maximum and minimum latitude (index 0) and maximum and minimum longitude (index 1) for all sensors in the entire data structure.

I could definitely work it out with a series of loops in the traditional way, but I'm wondering if there is some slick way to do this in Scala (I'm not an expert in Scala). Ultimately it's not a super-important question since I can do it with my own loops. Just thought it would make an interesting question, and if someone can find a nice solution it would be worth finding out.

Edit: Here's a more concrete example of how the data structure works. Here, R1S1 means Road #1, Sensor #1, etc.

Array(Map("R1S1"->Array(32,117), "R1S2"->Array(33,118)), Map("R2S1"->Array(32,116), "R2S2"->Array(34,118)))

Upvotes: 0

Views: 127

Answers (1)

David Maze
David Maze

Reputation: 158976

If you can just convert your data structure to a flat list of one part of the coordinates, then you can call min and max on that. If you could start from the inside and work your way out:

  1. Given the innermost Array[Double], you want to get the first element (or second).
  2. Given the containing map, you just want to get the values out.
  3. Given the containing array, flatten the array of arrays down to a single array.
  4. Take the maximum of the result.

You can essentially do this in reverse, working from the outside in, dealing only with containers, with no for loops. Here's a complete example:

// Say how to order Double values    
import Ordering.Double.IeeeOrdering

// Create a dedicated data structure for the coordinates
case class Coordinates(lat: Double, lon: Double)

// Find the minimum latitude value for your data structure
def minLat(world: Seq[Map[String, Seq[Coordinates]]]): Double =
  world               // Seq[Map[String, Seq[Coordinates]]]
    .map { _.values } // Seq[Seq[        Seq[Coordinates]]]
    .flatten          // Seq[            Seq[Coordinates] ]
    .flatten          // Seq[                Coordinates  ]
    .map { _.lat }    // Seq[                Double       ]
    .min

// Let's try it
val aWorld = Seq(Map(("a", Seq(Coordinates(-70, 40)))))
minLat(aWorld)  // -70

Upvotes: 1

Related Questions