简体   繁体   English

如何过滤scala中的元组列表?

[英]How to filter a list of tuples in scala?

I have the following list in Scala which I want to filter based on a criteria such that if there are any tuples with duplicate first value , Like from the below example I want to exclude 我在Scala中有以下列表,希望根据以下条件进行过滤:如果存在任何具有重复的第一个值的元组,就像下面的示例一样,我想排除

List((a,1), (a,2)) 

since it is having have "a" as duplicate . 因为它具有重复的“ a”。

You want to filter your result with a function that only leaves untouched those lists with no duplicate "keys" 您想要使用仅过滤那些没有重复“键”的列表的功能来过滤result

result filter noDuplicateKeys

This filtering function must take a list of pairs List[(A,B)] and return true only if the pair first element is not present elsewhere for all elements, and can be implemented as 此过滤函数必须获取对List[(A,B)]对的List[(A,B)]并且仅在所有元素的其他地方都不存在对第一个元素的情况下,才返回true。

def noDuplicateKeys[A, B](xs: List[(A, B)]) = 
    (xs groupBy (_._1)).values forall {_.size < 2}

It groups the elements into a Map whose keys are the A s and whose values are a corresponding list of the B s paired with that key. 它将元素分组到一个Map其键为A ,其值为与该键配对的B的对应列表。

From this values you can only accept those that have a size no more than 1 从此值中,您只能接受大小不超过1的那些

I believe that the following code will do what you want (to remove only the first pair, right?): 我相信以下代码将完成您想要的操作(仅删除第一对,对吧?):

I'm using pattern matching to do so, if you want to filter everything, u could do a recursion over your list or do what Kyle proposed. 我正在使用模式匹配来执行此操作,如果您想过滤所有内容,则可以对列表进行递归操作,也可以执行Kyle提出的建议。 Check this out: 看一下这个:

val a = "a"                                      
val b = "b"                                     

var result =
    List(
      List(),
      List((a, 1), (a, 2)),
      List((a, 1), (b, 1)),
      List((a, 1), (b, 2)),
      List((a, 2), (b, 1)),
      List((a, 2), (b, 2)),
      List((b, 1), (b, 2)),
      List((a, 1), (a, 2), (b, 1)),
      List((a, 1), (a, 2), (b, 2)),
      List((a, 1), (b, 1), (b, 2)),
      List((a, 2), (b, 1), (b, 2)),
      List((a, 1), (a, 2), (b, 1), (b, 2))) 

val filteredResult = (for (list <- result)
    yield list match {
    case x :: y :: xys if (x._1 == y._1) =>  xys
    case _ => list
  }).distinct

Result: 结果:

//> List()
//| List((a,1), (b,1))
//| List((a,1), (b,2))
//| List((a,2), (b,1))
//| List((a,2), (b,2))
//| List((b,1))
//| List((b,2))
//| List((a,1), (b,1), (b,2))
//| List((a,2), (b,1), (b,2))
//| List((b,1), (b,2))

The distinct will just filter the resulting empty lists. 唯一标识符将仅过滤结果空列表。

Cheers! 干杯!

I saw this as filtering out items from List[List[Tuple2[Char, Int]]] where an element of the list has the same elements. 我看到这是从List[List[Tuple2[Char, Int]]]中过滤掉项目,其中List[List[Tuple2[Char, Int]]]的元素具有相同的元素。 In this case an element of the list is List[Tuple2[Char, Int]] which I want to return a Boolean when the elements are the same. 在这种情况下,列表的元素是List[Tuple2[Char, Int]] ,当元素相同时,我想返回一个Boolean This List[Tuple2[Char, Int]] gets mapped to the first element of the Tuple and then logic is applied to the new list of chars using distinct and size to check if the elements are the same and to retain those that only have one element. List[Tuple2[Char, Int]]映射到Tuple的第一个元素,然后使用“ distinct”和“ size”将逻辑应用于新的char列表,​​以检查元素是否相同并保留只有一个元素的元素元件。

The filter 过滤器

filter(xs => xs.map(ys => ys._1).distinct.size != 1 || xs.size == 1)

Test data: 测试数据:

scala> val a = List(List(('a',1)))
a: List[List[(Char, Int)]] = List(List((a,1)))

scala> val aa = List(List(('a',1),('a',1)))
aa: List[List[(Char, Int)]] = List(List((a,1), (a,1)))

scala> val ab = List(List(('a',1),('b',1)))
ab: List[List[(Char, Int)]] = List(List((a,1), (b,1)))

scala> val aba = List(List(('a',1),('b',1),('a',1)))
aba: List[List[(Char, Int)]] = List(List((a,1), (b,1), (a,1)))

Test cases. 测试用例。

scala> a.filter(xs => xs.map(ys => ys._1).distinct.size != 1 || xs.size == 1)
res34: List[List[(Char, Int)]] = List(List((a,1)))

scala> aa.filter(xs => xs.map(ys => ys._1).distinct.size != 1 || xs.size == 1)
res35: List[List[(Char, Int)]] = List()

scala> ab.filter(xs => xs.map(ys => ys._1).distinct.size != 1 || xs.size == 1)
res36: List[List[(Char, Int)]] = List(List((a,1), (b,1)))

scala> aba.filter(xs => xs.map(ys => ys._1).distinct.size != 1 || xs.size == 1)
res37: List[List[(Char, Int)]] = List(List((a,1), (b,1), (a,1)))

based on the @pagoda_5b solution, I think we could find a better one. 基于@ pagoda_5b解决方案,我认为我们可以找到更好的解决方案。

What do you think about: 你有什么想法:

def noDuplicateKeys(l: List[(Char, Int)]): Boolean = l.toMap.size == l.size

list filter noDuplicateKeys

;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM