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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16206414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 05:13:38  来源:igfitidea点击:

Scala - finding a specific tuple in a list

scala

提问by mainas

I'm banging my head on the wall over this one. (fyi, I'm not a scala pro yet, but I'm loving it big time)

我正在用头撞墙。(仅供参考,我还不是 Scala 专家,但我很喜欢它)

Let's say we have this list of tuples:

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

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

The list has this signature:

该列表具有以下签名:

List[(Char, List[Int])]

My task is to get the "List[Int]" element from a tuple inside "data" whose key is, let's say for instance, letter "b".

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

In other words, if I implement a method like "findIntList(data, 'b')", then I expect a result of List(1, 1)

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

Just to complete the picture, I have tried the following approaches. The problem is that with all the approaches (except Approach 1, which I employ an explicit "return"), I either get a List[Option]or List[Any]object back, which I don't know how to extract the "List[Int]" information out of

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

Approach 1:

方法一:

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

Approach 2:

方法二:

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

Approach 3:

方法三:

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

Approach 4:

方法四:

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

回答by Jens Schauder

One of many ways:

多种方式之一:

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

toMapconverts a list of 2-tuples into a Mapfrom the first element of the tuples to the second. getgives you the value for the given key and returns an Option, thus you need another getto actually get the list.

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

Or you can use:

或者你可以使用:

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

Note: Only use get on Optionwhen you can guarantee that you'll have a Someand not a None. See http://www.scala-lang.org/api/current/index.html#scala.Optionfor how to use Option idiomatic.

注意:仅Option当您可以保证您将拥有 aSome而不是时才使用 get on None。有关如何使用 Option 惯用语,请参阅http://www.scala-lang.org/api/current/index.html#scala.Option

Update: Explanation of the result types you see with your different approaches

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

Approach 2: find returns an Option[List[Int]] because it can not guarantee that a matching element gets found.

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

Approach 3: here you basically do a map, i.e. you apply a function to each element of your collection. For the element you are looking for the function returns your List[Int] for all other elements it contains the value ()which is the Unitvalue, roughly equivalent to voidin Java, but an actual type. Since the only common super type of ′List[Int]′ and ′Unit′ is ′Any′ you get a ′List[Any]′ as the result.

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

Approach 4is basically the same as #3

方法4与#3基本相同

回答by chris

Another way is

另一种方式是

data.toMap.apply('b')

Or with one intermediate step this is even nicer:

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

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

where applyis used implicitly, i.e., the last line is equivalent to

whereapply是隐式使用的,即最后一行等价于

m.apply('b')

回答by Jatin

There are multiple ways of doing it. One more way:

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

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)

回答by korefn

You can try something like(when you are sure it exists) simply by adding type information.

您可以通过添加类型信息来尝试类似(当您确定它存在时)。

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

or use headOptionif your not sure the character exists

headOption在您不确定该字符是否存在时使用

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

回答by M Donkers

You can also solve this using pattern matching. Keep in mind you need to make it recursive though. The solution should look something like this;

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

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)
}

What this will do is walk your tuple list recursively. Check whether the head element matches your condition (the key you are looking for) and then returns it. Or continues with the remainder of the list.

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