Scala样式:适用于vs foreach,过滤器,地图等 [英] Scala style: for vs foreach, filter, map and others

查看:69
本文介绍了Scala样式:适用于vs foreach,过滤器,地图等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在scala中,最好的样式是高级迭代"而不是smth集合.在哪种情况下,我应该使用理解方法,何时应该寻找替代的迭代方式(就样式而言).在 Scala中的编程书中,有一个示例几乎像下一个示例:

What is the best style in scala for "advanced iteration" over collection of smth. In which cases I should use for-comprehension and when I should look for alternative way(in terms of style) of iteration. In Programming in Scala book there is an example that looks almost as next one:

for{
    file <- filesHere
    if file.getName.endsWith("txt")
    line <- Source.fromFile(file).getLines.toList
    if line.trim.matches(pattern)
  } println("|" + file + ": " + line.trim)

我尝试使用内部迭代重写它并得到:

I've tried to rewrite it using internal iteration and got:

filesHere foreach { file =>
  if (file.getName.endsWith("txt")) {
    Source.fromFile(file).getLines.toList foreach {line =>
      if (line.trim.matches(pattern)) println("|" + file + ": " + line.trim)
    }
  }
}   

但是,在网络上(包括stackoverflow),我发现有许多说服性的文章/帖子可用于理解,但我觉得使用起来并不方便.恕我直言,内部迭代非常容易阅读和方便.

However, on the web(including stackoverflow) I've found a lot of articles/posts persuading to use for-comprehension, I don't find it convenient for me to use it. IMHO, internal iteration is much readable and convenient.

关于此主题的最佳指导是什么?

What are the best guidelines on this topic?

推荐答案

我认为您正在学习Scala真是太好了.背后有一个很棒的社区,非常活跃,我认为随着时间的流逝,您对自己的决定会越来越满意.

I think it is great that you are learning Scala. There is a wonderful community behind it, very active, and I think that you'll be more-and-more pleased with your decision as time goes on.

至少目前来说,我认为您应该坚持"Scala编程",因为它写得很好,并且对语言有很棒的介绍.然后,Scala api文档本身就是一个不错的选择,因为许多类/方法都包含示例代码.另外,Google小组非常活跃(正如我所说,那里的人非常友好).

For the moment, at least, I think that you should stick to "Programming in Scala" as it is very well written and a terrific introduction to the language. Then, a good place to look will be the Scala api docs themselves as many of the classes/methods contain sample code. Also, the google group is very active (and, as I said, the people there are very friendly).

请记住,作为示例提供的代码不返回任何值,而只是产生副作用(在Java中,这将具有 void 返回值).大多数Scala API都围绕着具有返回值的副作用的函数(例如,您可能会有日志记录的副作用,但是惯用的Scala代码将使方法和函数的副作用最小化).

Keep in mind that the code you provide as an example returns no value, but rather just gives side-effects (in Java, this would have a void return value). Most of the Scala API is geared around functions with little to no side-effects that return a value (you might have, for example, a side-effect of logging, but idiomatic scala code will minimize side-effects in methods and functions).

在Scala API中,有一些方法可以满足您的需求(如果需要的话).例如,在Scheme中,您可以执行一个内部循环来进行迭代,在Scala中,它可能看起来像这样:

Within the Scala API, there are methods that would be the preferred style, if it matches your need. For example, in Scheme you might do an inner loop to iterate, in Scala it might look like this:

val myScores = List(4, 8, 6, 1, 2, 4, 9, 8)

def max(ls: List[Int]): Int = {
  def iter(acc: Int, rem: List[Int]): Int = {
    if (rem.isEmpty) acc
    else if (rem.head > acc) iter(rem.head, rem.tail)
    else iter(acc, rem.tail)
  }
  iter(ls.head, ls)
}

但是我不需要编写该函数,因为 max 已在列表API中实现:

But I don't need to write that function because max is already implemented in the list API:

myScores.max

因此,如果您要执行的操作已由库实现,则应使用该库. max()是一个简单的示例,但是在Scala API和 scalaz

So, if what you want to do is already implemented by a library, you should use that. max() is a trivial example, but there are much more complex transformations to be found in the Scala API and scalaz

用于理解的(您帖子的原始主题)是 flatMap map filter .如果您做的事情相当简单,那么两个版本的可读性都一样,但是如果您要编写一长串的 flatMap map filter 串在一起创建一个复杂的转换,那么 for -comprehension将更易读.

A for-comprehension (the original topic of your post) is a combination of flatMap, map, and filter. If you are doing something fairly simple, then both versions will be just as readable, but if you are doing a long chain of flatMap, map, and filter strung together to create a complex transformation, then a for-comprehension will be more readable.

针对您的问题,我认为 for -理解版本更容易阅读:

Specific to your question, I think the for-comprehension version is easier to read:

val filterMapFlatmapVersion: List[String] = 
  fileNames.filter(_.endsWith("txt")).flatMap { file =>
    io.Source.fromFile(file).getLines().toList.map(_.trim).filter(_ == pattern)
}

val forVersion: List[String] =
  for {
    fileName <- fileNames
    if fileName.endsWith("txt")
    line <- io.Source.fromFile(fileName).getLines()
    if line.trim().matches(pattern)
  } yield line.trim

这篇关于Scala样式:适用于vs foreach,过滤器,地图等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆