DDB
DDB

Reputation: 157

Elegant map implementation

having a list of ordered string to be compared to another list, I decided to implement one as a map in with the key is the first char of the string and the value the list of strings with the same first char. In short I have something as this:

var list1:Map[Char, List[String]] = Map('a' -> List("alone", "away"))
var list2:List[String] = List("I", "am", "alone", "at", "home", "watching", "batman", "XD")

Now, having implemented my code this way, it is "hard" to work with them trying to consider the first one as a simple list, so I was wondering if there was another more elegant way to solve this problem. If I have to verify if list1 has "alone", I have to first get the key 'a' and then call the method contains. I had to implement a thing like this.

if ( list1( "alone".charAt(0) ).contains( "alone" ) ) ...

It is ugly to have to extract each time the key and then compare the lists and I'd like to create a new map (or list) that implement this under the hood (it automatically extract the key and then work on the list). What do you suggest? Thanks.

EDIT: I rewrote part of the question clarifying some points. First list is ordered, the second one no.

Upvotes: 0

Views: 406

Answers (2)

Jens Schauder
Jens Schauder

Reputation: 81907

From all I have seen you really want just a list. So use a List. (Or possibly a SortedSet http://www.scala-lang.org/api/current/scala/collection/SortedSet.html)

You seem to be concerned about performance but you neither state what part of which algorithm is to slow, nor how much faster it needs to go, nor do you provide plausible arguments that the approach you choose does meet these performance requirements. So again: just use List. Then measure performance. If it really is to slow, create a benchmark from it post code and results here and state how fast it needs to go.

Then people will be able to help.

Upvotes: 4

Rex Kerr
Rex Kerr

Reputation: 167891

I'm not sure why using maps will help you compare lists of strings, but anyway:

If you don't mind using a mutable collection, and you are sure you have no repeats in your list (so you can actually use a set), then you can use the MultiMap trait:

import scala.collection.mutable._
val mm = new HashMap[Char,Set[String]] with MultiMap[Char,String]
Seq("alone","away").foreach(s => mm.addBinding(s(0),s))

scala> mm
res2: scala.collection.mutable.HashMap[Char,scala.collection.mutable.Set[String]]
 with scala.collection.mutable.MultiMap[Char,String] = 
 Map(a -> Set(alone, away))

scala> mm.entryExists('a',"alone")

Unfortunately, the multimappedness goes away when you use a collections operation (it's just a plain map from Char to Set[String] then).

Upvotes: 0

Related Questions