scala 比较两个列表中的项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17812486/
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
Comparing items in two lists
提问by blue-sky
I have two lists : List(1,1,1) , List(1,0,1)
我有两个列表: List(1,1,1) , List(1,0,1)
I want to get the following :
我想得到以下内容:
A count of every element that contains a 1 in first list and a 0 in the corresponding list at same position and vice versa. In above example this would be 1 , 0 since the first list contains a 1 at middle position and second list contains a 0 at same position (middle).
A count of every element where 1 is in first list and 1 is also in second list. In above example this is two since there are two 1's in each corresponding list. I can get this using the intersect method of class List.
在第一个列表中包含 1 并且在相应列表中在相同位置包含 0 的每个元素的计数,反之亦然。在上面的示例中,这将是 1 , 0 因为第一个列表在中间位置包含 1 ,而第二个列表在相同位置(中间)包含 0 。
每个元素的计数,其中 1 在第一个列表中,1 也在第二个列表中。在上面的例子中,这是两个,因为每个对应的列表中有两个 1。我可以使用类 List 的 intersect 方法来获得它。
I am just looking an answer to point 1 above. I could use an iterative a approach to count the items but is there a more functional method ? Here is the entire code :
我只是在寻找上述第 1 点的答案。我可以使用迭代方法来计算项目,但是否有更实用的方法?这是整个代码:
class Similarity {
def getSimilarity(number1: List[Int], number2: List[Int]) = {
val num: List[Int] = number1.intersect(number2)
println("P is " + num.length)
}
}
object HelloWorld {
def main(args: Array[String]) {
val s = new Similarity
s.getSimilarity(List(1, 1, 1), List(1, 0, 1))
}
}
回答by Jatin
For the first one:
对于第一个:
scala> val a = List(1,1,1)
a: List[Int] = List(1, 1, 1)
scala> val b = List(1,0,1)
b: List[Int] = List(1, 0, 1)
scala> a.zip(b).filter(x => x._1==1 && x._2==0).size
res7: Int = 1
For the second:
对于第二个:
scala> a.zip(b).filter(x => x._1==1 && x._2==1).size
res7: Int = 2
回答by pagoda_5b
You can count all combinations easily and have it in a map with
您可以轻松计算所有组合并将其放在地图中
def getSimilarity(number1 : List[Int] , number2 : List[Int]) = {
//sorry for the 1-liner, explanation follows
val countMap = (number1 zip number2) groupBy (identity) mapValues {_.length}
}
/*
* Example
* number1 = List(1,1,0,1,0,0,1)
* number2 = List(0,1,1,1,0,1,1)
*
* countMap = Map((1,0) -> 1, (1,1) -> 3, (0,1) -> 2, (0,0) -> 1)
*/
The trick is a common one
套路很常见
// zip the elements pairwise
(number1 zip number2)
/* List((1,0), (1,1), (0,1), (1,1), (0,0), (0,1), (1,1))
*
* then group together with the identity function, so pairs
* with the same elements are grouped together and the key is the pair itself
*/
.groupBy(identity)
/* Map( (1,0) -> List((1,0)),
* (1,1) -> List((1,1), (1,1), (1,1)),
* (0,1) -> List((0,1), (0,1)),
* (0,0) -> List((0,0))
* )
*
* finally you count the pairs mapping the values to the length of each list
*/
.mapValues(_.length)
/* Map( (1,0) -> 1,
* (1,1) -> 3,
* (0,1) -> 2,
* (0,0) -> 1
* )
Then all you need to do is lookup on the map
然后你需要做的就是在地图上查找
回答by Nicolas
Almost the same solution that was proposed by Jatin, except that you can useList.countfor a better lisibility:
几乎与 Jatin 提出的解决方案相同,不同之处在于您可以使用List.count更好的 lisibility:
def getSimilarity(l1: List[Int], l2: List[Int]) =
l1.zip(l2).count({case (x,y) => x != y})
回答by Vijay Kukkala
a.zip(b).filter(x => x._1 != x._2).size
回答by mohit6up
You can also use foldLeft. Assuming there are no non-negative numbers:
您也可以使用 foldLeft。假设没有非负数:
a.zip(b).foldLeft(0)( (x,y) => if (y._1 + y._2 == 1) x + 1 else x )
回答by senia
1) You could zip2 lists to get list of (Int, Int), collect only pairs (1, 0)and (0, 1), replace (1, 0)with 1and (0, 1)with -1and get sum. If count of (1, 0)and count of (0, 1)are the same the sumwould be equal 0:
1)你可以zip2所列出得到的名单(Int, Int),仅收集对(1, 0)和(0, 1),更换(1, 0)用1和(0, 1)用-1并获得总和。如果 count of(1, 0)和 count of(0, 1)相同,sum则相等0:
val (l1, l2) = (List(1,1,1) , List(1,0,1))
(l1 zip l2).collect{
case (1, 0) => 1
case (0, 1) => -1
}.sum == 0
You could use viewmethod to prevent creation intermediate collections.
您可以使用view方法来防止创建中间集合。
2) You could use filterand lengthto get count of elements with some condition:
2)您可以使用filter和length获取具有某些条件的元素数:
(l1 zip l2).filter{ _ == (1, 1) }.length
(l1 zip l2).collect{ case (1, 1) => () }.length

