0

我正在尝试从 scala 列表中创建一个元组:

.map('path -> ('uri1, 'uri2, 'uri3, 'uri4, 'uri5)) {elems:List[String] =>

  (elems(0), elems(1), elems(2), elems(3), elems(4)) //ouf of bounds!
}

但是elems可能有 1 到 5 个元素,所以很明显我会遇到索引越界异常。

这样做的scala /烫伤方式是什么?我猜正确的方法是迭代从 1 到 5 的范围并从那里生成元组。

null当元素不存在时,我想返回(出于兼容性原因)。

4

3 回答 3

5

这里的方法实际上取决于您的要求。

如果您Tuple5仅在定义了 5 个元素时才追求,elem那么简单的模式匹配是一种可行的方法(并且随着函数返回Option,您可以在 map 之后将其展平以获得预期结果):

  def convert(l: List[String]): Option[(String, String, String, String, String)] = l match {
    case e1 :: e2 :: e3 :: e4 :: e5 :: _ => Some((e1, e2, e3, e4, e5))
    case _ => None
  }

或者,如果您在获取所有列表大小并将它们转换为具有某些默认值的 Tuple5 之后,您可以:

  • 使用如上所示的模式匹配并处理剩余的 5 种情况(列表中的 0、1、2、3、4 元素)默认缺失值。

  • elem(n)用 scala.util.Try 和默认值(即Try(elem(1)).getOrElse(""))包装你的电话

  • 将默认值添加到elem列表中以填充缺失值

示例说明下面的最后一个选项:

  def convert(l: List[String], default : String): (String, String, String, String, String) = {
    val defaults = (1 to 5 - l.size).map(_ => default).toList
    l ++ defaults match {
      case e1 :: e2 :: e3 :: e4 :: e5 :: _ => (e1, e2, e3, e4, e5)
    }
  }
于 2014-06-17T11:08:22.380 回答
1

有一种方法可以在 1 行中执行此操作,让我们成为stringList默认值List[String]default

new Tuple(stringList.map(_.asInstanceOf[AnyRef]): _*) ++ (stringList.size until 5).map(_ => default)

问题在于它不是类型安全的,所以我给了 Norbert 一个赞成票,因为他的回答是——而且可能更容易阅读。

于 2014-06-17T15:12:14.067 回答
1

您可以根据需要用空值填充列表:

.map('path -> ('uri1, 'uri2, 'uri3, 'uri4, 'uri5)) {elems:List[String] =>
  val padded= elems ++ List.fill(5)(null)
  (padded(0), padded(1), padded(2), padded(3), padded(4))  //No ouf of bounds!
}
于 2014-06-17T22:48:19.877 回答