【问题标题】:How to make this condition more Scala-like如何使这种情况更像 Scala
【发布时间】:2011-11-02 00:06:43
【问题描述】:

我有以下方法:

def generateAssociatedImages : List[ImageFileEntry] = {

    if ( this.page > 1 && this.page < this.fileEntry.pageCount ) {
        List( copyWithPage( this.page - 1 ), copyWithPage( this.page + 1 ) )
    } else {
        if ( page == 1 && page != file.fileEntry.pageCount ) {
            List( copyWithPage( this.page + 1 ) )
        } else {
            List( copyWithPage( this.page - 1 ) )
        }
    }

}

但是这个看起来太像 Java(如果我使用的是 Ruby,我会在一个范围上做一个 switch/case,然后做其他比较)。在 Scala 中有没有更实用的方法来做到这一点?

行为很简单:

  • 如果输入为第 1 页且总页数为 3,则输出为 [2]
  • 如果输入为第 2 页,总页数为 3,则输出为 [1,3]
  • 如果输入为第 3 页且总页数为 3,则输出为 [2]

我正在寻找一个惯用的解决方案,我还是 Scala 的新手。

如果我能做这样的事情那就太好了:

( 1 until 3 ).hasNext( 2 )

【问题讨论】:

  • 如果只有一页怎么办?在您的 sn-p 中,它似乎回答 [0](根据您的符号)它有效吗?
  • 在此之前还有另一种方法,如果只有一个页面,则不会尝试生成图像。

标签: java scala idioms


【解决方案1】:

假设在一页上,图像列表为空,您可以有以下内容:

def generateAssociatedImages: List[ImageFileEntry] = {
    val pageCount = fileEntry.pageCount
    page match {
        case `pageCount` if page == 1 => List()
        case `pageCount` => List(copyWithPage(pageCount - 1))
        case 1 => List(copyWithPage(2))
        case x => List(copyWithPage(x - 1), copyWithPage(x + 1))
    }
}

【讨论】:

  • 太好了,正是我想要的。问题,为什么那里有智能引号?
  • 否则pageCount 将被视为match 块范围内的新变量(您永远不会比第二种情况更进一步)。
  • 你可以通过大写PageCount来达到同样的效果。
  • 是的,但我更喜欢为对象保留大写字母。这取决于您的代码指南或您的偏好。
【解决方案2】:
def ifTrue[T](c : Boolean, v : =>T) = if (c) Some(v) else None

def generateAssociatedImages = List(ifTrue(this.page > 1, -1)), ifTrue(this.page < this.fileEntry.pageCount, 1)).flatten.map(d => copyWithPage(this.page + d))

【讨论】:

  • 即使它产生了很好的结果,它看起来也很不可读,不是吗?
  • 是的,它在这里变得更加难以阅读,但很高兴看到这一点,因此我们可以避免使用聪明的代码。
  • 可读性在旁观者的眼中。我的代码消除了重复,例如您的代码有四个对 copyWithPage 的调用和两个相同页面索引逻辑的副本。
【解决方案3】:

您在寻找相邻的页面吗?

val pages = 1 to this.fileEntry.pageCount

implicit def toNext(r: Range) = new { 
    def next(n: Int) = r.view sliding 2 find (n == _.head) map (_.last)
}

def adjacent(page: Int) = List(pages next page, pages.reverse next page).flatten

def generateAssociatedImages : List[ImageFileEntry] = 
    adjacent(this.page) map copyWithPage

我承认,这有点过度设计。但它很优雅。由于sliding 中的错误,它也不适用于单页范围。

【讨论】:

    猜你喜欢
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2015-11-30
    相关资源
    最近更新 更多