【问题标题】:Scala for-loop. Getting index in consice wayScala for 循环。以简洁的方式获取索引
【发布时间】:2013-05-28 20:16:10
【问题描述】:

在这段代码中,我想增加 index 以将其放入每个 yielding 结果中。

var index=0

for(str <- splitToStrings(text) ) yield  {

  if (index != 0) index += 1               // but index is equal to `0` all the time

  new Word(str, UNKNOWN_FORM, index )
}

为什么我不能更改 index ?那么实现这个逻辑的最佳方法是什么,尽量简洁?

【问题讨论】:

    标签: scala loops yield


    【解决方案1】:

    因为最初 index 设置为 0,因此您的条件 index != 0 永远不会执行为 true,并且 index 永远不会增加。 也许你不需要这个条件?也许你可以在之后计算结果? 现在我看到在循环中使用了索引。然后你必须要么使用@BenJames answer 要么递归。

    【讨论】:

    • 是的。这对我来说太愚蠢了。至少我很高兴产量不足为奇。 (我之所以放它是因为我想从 0-index 开始)。我倾向于认为由于 scala 而不是我:)。但是这个不同的情况 %) 我最近有很多惊喜.. 这就是为什么
    【解决方案2】:

    大多数类似序列的集合上的zipWithIndex 方法将为您提供一个从零开始的索引,并随着每个元素递增:

    for ((str, index) <- splitToStrings(text).zipWithIndex)
      yield new Word(str, UNKNOWN_FORM, index)
    

    【讨论】:

    • 很好。我已经看到了这种转变。但它仍然处于被动知识中。确实很简洁。
    • 那不是效率低下吗?
    【解决方案3】:
    splitToStrings(text).foldLeft(0,List[Word]){(a,b) => {
       if(a._1!=0) (a._1+1,new Word(str, UNKNOWN_FORM, index) :: b)
       else (a._1,new Word(str, UNKNOWN_FORM, index) :: b)
    }}
    

    我在这里使用foldLeft 和一个元组作为:以index = 0 和一个空的List 开头。然后我遍历每个元素。

    a 上方是这个元组。我检查index 值并增加它。否则我不添加index。我将新的Word 添加到列表中。

    最终你会得到一个包含索引值的元组和包含所有单词的总列表。

    【讨论】:

    • 这样的代码可以很容易地使用一些解释性的词来配合它。
    【解决方案4】:

    zipWithIndex 将复制并创建一个新集合,所以当集合可能很大时最好让它变得懒惰

    for ((str, index) <- splitToStrings(text).view.zipWithIndex)
      yield new Word(str, UNKNOWN_FORM, index)
    

    事实上,如果您正在使用索引序列,那么更有效的方法是使用indices,它会生成该序列的所有索引的范围。

    val strs = splitToStrings(text)
    
    for(i <- strs.indices) yield  {
      new Word(strs(i), UNKNOWN_FORM, i )
    }
    

    【讨论】:

    • 这将一直遍历整个列表以按索引获取项目:strs(i)。可能很慢。
    • 更新了答案。为了提供良好的随机访问性能,需要对序列进行索引。
    猜你喜欢
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 2014-04-20
    • 2012-08-20
    • 2013-03-19
    • 1970-01-01
    相关资源
    最近更新 更多