2016-08-19 3 views
1

Скажем, у меня есть этот код, чтобы выяснить Dups в списке на основе параметра конструктора: (я закончил с этим после разбора некоторых текстовых файлов, которые имеют дубликаты.)Как фильтровать список с другим списком на основе некоторых условий?

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, чтобы отфильтровать дубликаты на основе некоторых других правил?

В конце концов, я хочу иметь список без дубликатов, но я также хочу сохранить как можно больше информации из свойств ini и com. Это означает, что я хочу сохранить дубликат, который следует одно из следующих правил:

  • Линии с содержанием в собственности ini и com имеют приоритет над всеми остальными, а это означает: Line("X", "hello", "some text") против Line("", "hello", "some text") против Line("", "hello", "") следует отдать первым

  • Линия с содержанием в собственности com имеет приоритет над ini, что означает: Line("", "hello", "") против Line("", "hello", "some text") должен отдать последние один

  • Линия с содержанием в собственности ini имеет приоритет над линиями с чем в INI или ком, то есть: Line("X", "hello", "") против Line("", "hello", "") должен вернуть первый

  • в случае, если оба дубликаты имеют информацию в ini и com, я не Не заботьтесь о том, какой из них выбран.

Интересно, не слишком ли это сложно, и может быть другой способ решить эту проблему. Все, что я хочу выполнить, - это список, в котором больше нет дубликатов, в то же время сохраняя этот дубликат, который имел большую информацию об этом. Как бы это решить?

ответ

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)) 
+0

Потрясающие ! Короткий и очень понятный. – User1232187

Смежные вопросы