【问题标题】:Avoiding loops in Scala避免 Scala 中的循环
【发布时间】:2014-01-24 06:36:13
【问题描述】:

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

例如,“network”和“workout”的相似度为 1。“House”和“Mouse”的相似度为 4。

以下是我将如何以非常老式的 C# 方式进行操作:

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;
}

到目前为止,我在 scala 中所做的是编写一个尾递归函数以避免循环:

@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
}

但我不太确定这是否是 Scala 中的最佳实践。例如,有没有什么方法可以让 Collection Combinators (zip, filter) 更优雅?

【问题讨论】:

    标签: scala loops collections


    【解决方案1】:
    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
    

    您可以在此处删除方法view。在这种情况下,您将创建一个新的元组集合(Char, Char),大小为min(first.size, second.size)。对于小字符串(单个单词),您不会遇到性能问题。

    替代实现:

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

    【讨论】:

    • 为了完整性和将来的参考,C#中相同方法的主体可能是return first.Zip(second, Tuple.Create).Count(t =&gt; t.Item1 == t.Item2);,所以非常相似。 :)
    • @PatrykĆwiek:我猜first.Zip(second, (a, b) =&gt; a == b).Count(t =&gt; t) 更好(没有不必要的Tuple 创作,我只是不喜欢ItemN_N 方法)。
    • 真正的好收获!不幸的是,C# 缺乏类似于 Scala 和 F# 的语法糖和对元组的支持,我只是想尽可能接近您的解决方案。
    • 谢谢@senia,这正是我要找的!只是跟进 - 在这种情况下,“视图”到底有什么好处?是为了以懒惰的方式创建元组吗? '(first.iterator zip second)' 也可以吗? PS:感谢PatrykĆwieksenia,目前我还没有在C#中使用Zip扩展方法,所以我会记住这一点!
    • @AlexanderWeber: Could an '(first.iterator zip second)' do it as well?,是的,但你应该使用(first.iterator zip second.iterator)Iterator 是可变的,视图是不可变的。它可能会导致一些strange errors,所以我更愿意避免使用迭代器。
    猜你喜欢
    • 2011-03-20
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    相关资源
    最近更新 更多