【问题标题】:Pattern matching lists of certain size or greater/less特定大小或更大/更少的模式匹配列表
【发布时间】:2013-04-09 15:27:44
【问题描述】:

在 Scala 中,有没有办法指定与大小更大(或更小)或等于某个值的 List 匹配的模式?

例如,如果我想对所有大小为 3 或以下的列表应用相同的操作:

list match {
    case Nil => op(list) 
    case x :: Nil => op(list)
    case x :: y :: Nil => op(list)
    case x :: y :: z :: Nil => op(list)
    case x :: tail => other(list)
} 

有没有办法将这种情况减少到两种情况?

【问题讨论】:

  • 我认为这可以通过一个守卫来完成...case... if (tail.size >= x) =>

标签: list scala pattern-matching


【解决方案1】:

是的,尽管您需要颠倒这些案例的顺序:

list match {
  case l @ (_ :: _ :: _ :: _) => other(l)
  case l => op(l)
}

请注意,我已将新变量 l 绑定到模式中的列表,而不是引用 list,并且当我不需要变量时,我使用了 _。我建议坚持这两种做法,但如果没有它们,答案将完全相同。

【讨论】:

  • 当保护条件完成问题中提出的工作时,我看不出使用这种混淆语法的意义。
  • @DenisR.:首先,我按要求回答了这个问题,其次,我不确定这个答案实际上是否比使用列表时的警戒条件更惯用,其中@ 987654325@ 是一项昂贵的操作。如果你想避免遍历列表(你应该),你必须写类似case l if l.lengthCompare(3) > -1的东西,这本身就是一种尴尬。
  • 您对复杂性和使用长度比较是正确的。我更喜欢这个解决方案,因为长度是明确写的,而不是写成“_”-1的数字。谢谢你的解释。
  • 谢谢。为什么建议使用l 而避免使用list?在以下情况下,您将如何区分:长度为 1、任意长度和空列表?
【解决方案2】:

如果你坚持使用模式匹配(也许你想包含更多的匹配案例?),你可以为它使用一个保护条件

list match {
    case l if(l.size <= 3) => op(l)
    case l => other(l)
}

【讨论】:

  • 使用 lengthCompare 将列表长度与 3 进行比较会更有效
【解决方案3】:

一个普通的 if / else 有什么问题??

if (list.length >= minimumLength)
  longer(list)
else
  shorter(list)

【讨论】:

  • 如果列表真的很长怎么办?不使用长度的匹配/大小写会更好...
  • 我不确定“真的很长”可能是什么,但Lists 对每个元素持有相当大的大小开销,并且对于非常大的集合没有强烈指示。它们真的只有一个大优点:非常有效的头/尾分解。
【解决方案4】:

你也可以这样做:

list.splitAt(len) match {
   case (xs, Nil) => other(xs)
   case (_, _) => op(list)
}

而且复杂性是O(len),因此即使列表很长,len 也是决定因素。

上面调用op if list.size &lt; len else 调用other

【讨论】:

    猜你喜欢
    • 2019-10-09
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-01
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    相关资源
    最近更新 更多