Reputation: 799
I am very new to Scala and the whole functional programming style. What I need to do is calculating the similarity between two Strings by comparing each letter of both words. The function will be used with words of same length.
For example "network" and "workout" would have a similarity of 1. "House" and "Mouse" would have a similarity of 4.
Here is how I would do it in a very old fashioned C# way:
int calculateCharSimilarity(string first, string second)
{
int similarity = 0;
for(int i = 0; i < first.lenght() && i < first.lenght(); i++)
{
if(first.charAt(i) == second.charAt(i))
similarity++;
}
return similarity;
}
What I did in scala so far is to write a tail recursive function in order to avoid the loop:
@tailrec
private def calculateCharSimilarity(first: Seq[Char], second: Seq[Char], similarity: Int = 0): Int = {
if(first != Nil && second != Nil)
calculateCharSimilarity(first.tail, second.tail, if(first.head == second.head) similarity + 1 else similarity)
else
similarity
}
But I am not so sure if that is best practise in Scala. Isn't there any way to do it more elegant with Collection Combinators (zip, filter) for example?
Upvotes: 6
Views: 1372
Reputation: 38045
def charSimilarity(first: String, second: String) =
(first.view zip second).count{case (a, b) => a == b}
charSimilarity("network", "workout")
// Int = 1
charSimilarity("House", "Mouse")
// Int = 4
You could drop method view
here. In this case you'll create a new collection of tuples (Char, Char)
of size min(first.size, second.size)
. For small strings (single word) you'll get no performance issue.
Alternative implementation:
(first, second).zipped.count{case (a, b) => a == b}
Upvotes: 10