Scala - 在列表中查找特定元组

时间:2013-04-25 04:29:59

标签: scala

我正在把这个头撞在墙上。 (fyi,我还不是scala pro,但我非常喜欢它)

假设我们有这个元组列表:

val data = List(('a', List(1, 0)), ('b', List(1, 1)), ('c', List(0)))

该列表有这个签名:

List[(Char, List[Int])]

我的任务是从“数据”中的元组中获取“List [Int]”元素,其中的键是,例如,字母“b”。

换句话说,如果我实现像“findIntList(data,'b')”这样的方法,那么我期待List(1,1)的结果

为了完成图片,我尝试了以下方法。问题是,所有的方法(除了方法1,我使用一个明确的“返回”),我要么得到一个List[Option]List[Any]对象,我不知道如何提取

中的“List[Int]”信息

方法1:

data.foreach { elem => if (elem._1 == char) return elem._2 }

方法2:

data.find(x=> x._1 == ch)

方法3:

for (elem <- data) yield elem match {case (x, y: List[Bit]) => if (x == char) y}

方法4:

for (x <- data) yield if (x._1 == char) x._2

5 个答案:

答案 0 :(得分:18)

许多方法之一:

data.toMap.get('b').get

toMap将元组列表从元组的第一个元素转换为Map到第二个元组。 get为您提供给定键的值并返回Option,因此您需要另一个get来实际获取列表。

或者您可以使用:

data.find(_._1 == 'b').get._2 

注意:只有当您可以保证Option而不是Some时才使用get None。有关如何使用Option idiomatic的信息,请参阅http://www.scala-lang.org/api/current/index.html#scala.Option

更新:您使用不同方法看到的结果类型说明

方法2 :find返回Option [List [Int]],因为它无法保证找到匹配的元素。

方法3 :这里你基本上做了map,即你将一个函数应用到你的集合的每个元素。对于您要查找的元素,函数返回List [Int],包含值()的所有其他元素,Unit值,大致相当于Java中的void,但是实际的类型。由于'List [Int]'和'Unit'的唯一常见超类型是'Any',因此您会得到'List [Any]'。

方法4 与#3基本相同

答案 1 :(得分:1)

另一种方式是

data.toMap.apply('b')

或者通过一个中间步骤,这甚至更好:

val m = data.toMap
m('b')

其中隐式使用apply,即最后一行等同于

m.apply('b')

答案 2 :(得分:1)

有多种方法可以做到这一点。还有一种方法:

scala> def listInt(ls:List[(Char, List[Int])],ch:Char) = ls filter (a => a._1 == ch) match {
 | case Nil => List[Int]()
 | case x ::xs => x._2
 | }
listInt: (ls: List[(Char, List[Int])], ch: Char)List[Int]
scala> listInt(data, 'b')
res66: List[Int] = List(1, 1)

答案 3 :(得分:0)

您只需添加类型信息即可尝试(当您确定它存在时)。

val char = 'b'
data.collect{case (x,y:List[Int]) if x == char => y}.head

或如果您不确定角色是否存在,请使用headOption

data.collect{case (x,y:List[Int]) if x == char => y}.headOption

答案 4 :(得分:0)

您也可以使用模式匹配来解决此问题。请记住,你需要使它递归。解决方案看起来应该是这样的;

def findTupleValue(tupleList: List[(Char, List[Int])], char: Char): List[Int] = tupleList match {
  case (k, list) :: _ if char == k => list
  case _ :: theRest => findTupleValue(theRest, char)
}

这将做的是递归地遍历你的元组列表。检查head元素是否与您的条件(您要查找的键)匹配,然后返回它。或继续列表的其余部分。