2013-08-07 2 views
3

У меня есть список, содержащий что-то вроде:Расщепление список в два списка в Скале

val lines: List[String] = List("bla blub -- id_1", "sdkfjdf -- id_2", "blubber blab -- id_1", "foo -- id_3", "ieriuer -- id_2", "bar -- id_3") 

Так в основном список содержит идентификатор, который существует ровно в два раза (id_x) и строку, которая принадлежит одному из идентификаторов ,

Я хочу, чтобы разделить, что один список в два списка, которые затем каждая из них содержит уникальный набор id_s с их принадлежащими строк, как это:

l1("bla blub -- id_1", "sdkfjdf -- id_2", "foo -- id_3") 
l2("blubber blab -- id_1", "ieriuer -- id_2", "bar -- id_3") 

Как я хотел бы сделать, что в функциональном образом?

С наилучшими пожеланиями, Sven

+0

Благодарим вас за добавление кодовых блоков :-) – sveri

ответ

3
lines.groupBy(_.split(" -- ")(1)).toList.map(_._2).transpose 

Это грубый и готовый способ сделать это; на самом деле, если вы хотите сделать что-то больше с этими данными, вероятно, будет лучше разобрать элементы в случае класс, а-ля:

case class Item(id: String, text: String) 
val items = for { 
    line <- lines 
    Array(text, id) = line.split(" -- ") 
} yield Item(id, text) 

затем сделать то же самое, что и выше, за исключением groupBy(_.id) и удобно sortBy(_.id) также.

+0

Это работает, спасибо большое, я не знал о транспорте. Однако знаете ли вы о версии, которая может быть парализована в списке? – sveri

+0

'lines.par.groupBy ...' должен делать трюк. Не гарантируется, что быстрее, особенно для небольших списков. –

1

Как об этом решении?

lines.groupBy(_.takeRight(3)).map(_._2).foldLeft((List.empty[String], List.empty[String])) { 
    (acc, elem) => elem match { 
    case left :: right :: Nil => 
     (left :: acc._1, right :: acc._2) 
    case Nil => acc 
    } 
} 

res2: (List[String], List[String]) = (List(bla blub -- id_1, sdkfjdf -- id_2, foo -- id_3),List(blubber blab -- id_1, ieriuer -- id_2, bar -- id_3)) 
Смежные вопросы