我正在尝试从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 / scalding方法是什么?我猜测正确的方法是迭代1到5的范围并从那里生成元组。
当元素不存在时,我想返回null
(出于兼容性原因)。
答案 0 :(得分: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 elems)默认缺失值。
使用scala.util.Try和默认(即elem(n)
)
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)
}
}
答案 1 :(得分:1)
有一种方法可以在一行中执行此操作,stringList
为List[String]
,default
为默认
new Tuple(stringList.map(_.asInstanceOf[AnyRef]): _*) ++ (stringList.size until 5).map(_ => default)
问题在于它不是类型安全的,所以我给了Norbert一个upvote,因为他的回答是 - 而且可能更容易阅读。
答案 2 :(得分: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!
}