Scala从Option emelents列表中创建Map?
myMap = (0 to r.numRows - 1).map { i =>
if (Option(r.getValue(i,"Name")).isDefined)
(r.getValue(i, "Name")) -> (r.getValue(i, "isAvailable").toString)
}.toMap
foo(myMap) //here At this point, I'm geting the exception
我已经尝试了上面的代码,但没有编译:
Exception:
Error:(158, 23) Cannot prove that Any <:< (T, U).
}.toMap
^
答案 0 :(得分:1)
也许试试这段代码:
val myMap = (0 until r.numRows) flatMap { i =>
for {
name <- Option(r.getValue(i, "Name"))
available = r.getValue(i, "isAvailable").toString
} yield (name, available)
}.toMap
foo(myMap)
您的问题很可能是在没有if
的情况下使用else
,而if
是scala中的表达式,这意味着它会评估某些内容。
if (2 > 3) true
相当于
if (2 > 3) true else ()
所以类型是Unit
和Boolean
的常见超类型Any
,这就是你得到的错误。
请注意,您可以将to
和-1
替换为until
,Option
执行相同的操作,但更具可读性。
您不应该使用isDefined
真正检查map
并对结果执行操作,如果这是真的,为此您使用for
操作。
稍微解释一下我的实现:Option[(String, String)]
部分将评估为"Name"
,如果存在None
密钥则会包含您的元组,其他方式flatMap
。从概念上讲,Option[(String, String)]
将首先将您的索引范围更改为None
的序列,然后展平它,即删除所有Some
并展开所有"isAvailable"
。
如果你想检查for {
name <- Option(r.getValue(i, "Name"))
available <- Option(r.getValue(i, "isAvailable"))
} yield (name, available.toString)
是否为空,你可以做类似的事情
const foo = c => {
let rec = acc => x => x === undefined ? rec(acc + "o") : foo(acc + x);
return c === undefined ? rec("o") : "f" + c;
};
foo('t'); // "ft"
foo()('t'); // "fot"
foo()()('t'); // "foot"