【问题标题】:Dynamic For Comprehensions动态的理解
【发布时间】:2017-12-09 00:06:37
【问题描述】:

我对 Scala 比较陌生,所以我对这门语言不是很有信心,我需要你的帮助来解决问题。我知道 for-comprehension 只是简化复杂 map/flatMap 层次结构的语法糖。

现在,考虑有 3 个不同的 Range 区间,应该将它们组合起来以创建所有可能的值组合(尊重区间)。

示例

使用for-comprehension可以解决问题:

val intervalX = 1 to 5
val intervalY = 6 to 13
val intervalZ = 20 to 50
for {
  x <- intervalX;
  y <- intervalY;
  z <- intervalZ
} yield (x,y,z)

Scala 编译器将其转换为:

intervalX.flatMap{x =>
    intervalY.flatMap{y =>
        intervalZ.map{z => (x,y,z)}
    }
}

但是,如果在输入中给出一个变量 d 个间隔,问题就会变得更加困难。是否可以执行相同的操作,获得所有可能的 d 元组?我认为可以使用 foldLeft 操作来解决它,但我目前无法正确编写它。你能帮帮我吗?

谢谢

【问题讨论】:

  • 有很多样板文件是可能的,但我建议使用一个库来帮助尽可能地减少样板文件,我认为 shapeless 是理想的选择。 (另请注意,元组支持到 22,所以 d 应该是 &lt;=22。)
  • 谢谢。我不知道这个图书馆。关于我应该研究哪些功能,您能否给我一个提示?
  • 例如,如果输入是HListRanges,则结果可以是HList 的组合。此外,shapeless.syntax.std.tuple 部分可能更接近您的预期。

标签: scala


【解决方案1】:

如果您可以在没有元组的情况下生存,那么使用 foldLeft 并返回表示组合的列表的版本可能是:

val intervalX = 1 to 5
val intervalY = 6 to 13
val intervalZ = 20 to 50
val ranges = intervalZ :: intervalY :: intervalX :: Nil
val combos = ranges.foldLeft(Iterable[Seq[Int]](Nil)) { case (c, e) =>
   for {
      i <- e
      j <- c
   } yield i +: j
}
combos foreach { println(_) }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-28
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    相关资源
    最近更新 更多