Reputation: 15365
I want to find a key in a map that is similar to a specific text. should I use for loop or is there a more elegant way?
Upvotes: 4
Views: 3746
Reputation: 1062
It really depends on what you mean by 'similar to' and 'text'. If you are using English words you could use the Soundex algorithm (http://en.wikipedia.org/wiki/Soundex) to give you a code for each word and use that as a hash key, collecting all the words with the same Soundex value together in a list. If you want to do full text matching then it's a lot more complicated and you need to use techniques such as Inverted Indexes (http://en.wikipedia.org/wiki/Inverted_index). In that case you'd be best looking at something pre-written such as Apache Lucene (http://lucene.apache.org/java/docs/) which gives you much more besides simple inverted indexes. Lucene is written in Java, so it is directly usable from Scala.
Upvotes: 0
Reputation: 41646
The direct translation of your question is map.keys.find(_.matches(pattern))
which given a map, gets they keys and finds the first key that matches the regexp pattern.
val map = Map("abc" -> 1, "aaa" -> 2, "cba" -> 3)
map.keys.find(_.matches("abc.*"))
// Some(abc)
map.keys.find(_.matches("zyx"))
// None
A loop may be counter productive if you don't want to scan all keys.
Upvotes: 9
Reputation: 134270
Suppose you have some regular expression which you wish to match on:
val RMatch = """\d+:(\w*)""".r
And a function, which takes the matched group for the regex, and the value in the map
def f(s: String, v: V): A
Then you can match on the regex and collect the value of the function:
map collectFirst { case (RMatch(_), v) => f(txt, v) }
If you just wanted the value...
map collectFirst { case (RMatch(txt), v) => v }
Note: the implementation of this method effects a traversal on the map, in case that is not what you were desiring
Upvotes: 8
Reputation: 19345
It depends on the pattern and the map's underlying implementation. If the map is a HashMap
, then it can only give you an exact match against a key, so you can't do anything better than loop over its keys. If the map is a SortedMap
and you know the beginning of the text you're looking for, then you can use the range
method to obtain a part of the map based on the pattern, and loop over that range.
Upvotes: 0