避免Scala中的循环

避免Scala中的循环,scala,loops,collections,Scala,Loops,Collections,我对Scala和整个函数式编程风格非常陌生。我需要做的是通过比较两个单词的每个字母来计算两个字符串之间的相似性。该函数将与相同长度的单词一起使用 例如,“网络”和“锻炼”的相似性为1。“房子”和“老鼠”的相似性为4 下面是我将如何用一种非常老式的C#方式来做这件事: int-calculateCharSimilarity(字符串第一,字符串第二) { int相似性=0; 对于(int i=0;ia==b).Count(t=>t)更好(没有不必要的Tuple创建,我只是不喜欢ItemN和\N方法)

我对Scala和整个函数式编程风格非常陌生。我需要做的是通过比较两个单词的每个字母来计算两个字符串之间的相似性。该函数将与相同长度的单词一起使用

例如,“网络”和“锻炼”的相似性为1。“房子”和“老鼠”的相似性为4

下面是我将如何用一种非常老式的C#方式来做这件事:

int-calculateCharSimilarity(字符串第一,字符串第二)
{
int相似性=0;
对于(int i=0;i
到目前为止,我在scala中所做的是编写一个尾部递归函数,以避免循环:

@tailrec
私有定义计算相似性(第一个:Seq[Char],第二个:Seq[Char],相似性:Int=0):Int={
如果(第一个!=Nil&&second!=Nil)
计算相似性(first.tail,second.tail,if(first.head==second.head)相似性+1 else相似性)
其他的
相似性
}
但我不确定这是否是Scala的最佳实践。例如,是否有任何方法可以使用集合组合器(zip、filter)实现更优雅的效果

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
您可以在此处删除方法
视图
。在本例中,您将创建一个新的元组集合
(Char,Char)
,其大小为
min(first.size,second.size)
。对于小字符串(单个单词),您不会遇到性能问题

替代实施:

(first, second).zipped.count{case (a, b) => a == b}

为了完整性和将来的引用,C#中相同方法的主体可以是
returnfirst.Zip(第二个,Tuple.Create).Count(t=>t.Item1==t.Item2),非常相似。:)@PatrykĆwiek:我猜
第一个.Zip(第二个,(a,b)=>a==b).Count(t=>t)
更好(没有不必要的
Tuple
创建,我只是不喜欢
ItemN
\N
方法)。真的很好!不幸的是,C#缺乏语法糖和对类似Scala和F#的元组的支持,我只是想尽可能接近您的解决方案。谢谢@senia,这正是我想要的!接下来,在这种情况下,“查看”到底有什么好处?是为了以一种懒惰的方式创建元组吗?(first.iterator-zip second)也可以这样做吗?PS:谢谢PatrykĆwiek和senia,到目前为止我没有在C#中使用Zip扩展方法,所以我会记住这个方法@亚历山德韦伯:
一个“(first.iterator-zip-second)”也可以吗?
,是的,但是你应该使用
(first.iterator-zip-second.iterator)
<代码>迭代器是可变的,视图是不可变的。它可能会导致一些错误,所以我更喜欢避免使用迭代器。