如何根据某些条件使用其他列表过滤列表?

时间:2016-08-19 09:33:21

标签: scala comparison filtering case-class

假设我有这个代码来根据构造函数参数找出List中的重复:(在解析了一些有重复文本的文本后,我最终得到了这个。)

case class Line(ini: String, name:String, com:String)

val l0 = Line("X", "hello", "some text")
val l1 = Line("", "world", "some text")
val l2 = Line("X", "computer", "")
val l3 = Line("", "hello", "")
val l4 = Line("X", "world", "")
val l5 = Line("", "hello", "some stuff")

val lineList = List(l0,l1,l2,l3, l4, l5)

val dup = lineList.groupBy(_.name).collect { case (x, List(_,_,_*)) => x } // should yield List("hello", "world")

现在我知道哪一个是重复的。但是,如何再次过滤lineList以根据其他一些规则过滤掉重复项?

最后,我想要一个没有重复项的List,但我也希望尽可能多地保留属性inicom中的信息。这意味着我想保留遵循以下规则之一的副本:

  • 属性inicom中内容的行优先于所有其他行,这意味着: Line("X", "hello", "some text") vs Line("", "hello", "some text") vs Line("", "hello", "")应该回馈第一个

  • 属性com中包含内容的行优先于ini,这意味着: Line("", "hello", "") vs Line("", "hello", "some text")应该返回最后一个

  • 属性ini中包含内容的行优先于ini或com中没有任何内容的行,这意味着: Line("X", "hello", "") vs Line("", "hello", "")应该返回第一个

  • 如果两个重复项都包含inicom中的信息,我不关心选择哪一个。

我想知道这是不是过于复杂,可能还有另一种解决方法。我想要完成的只是一个没有更多重复的List,同时保留那些拥有最多信息的dup。如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

您可以定义一个chooseBetterLine函数,它可以为任意两个具有相同名称的行执行所需的逻辑(我希望我能正确地遵循它) - 然后在值上使用reduce

def chooseBetterLine(l1: Line, l2: Line): Line = {
  if (l1.ini.nonEmpty && l2.ini.isEmpty) l1
  else if (l1.com.nonEmpty && l2.com.isEmpty) l1
  else l2
}

val result: Iterable[Line] = lineList.groupBy(_.name).values.map(_.reduce(chooseBetterLine))