2014-09-22 3 views
-1

данный объект:Scala collectons фильтровать и сортировать последовательность с объектами, содержащими карту, а затем итерацию над ней

case class GT(code: String,names: Map[String, Option[String]]) {} 

и

список:

val gText = List(new GT("USB", Map("de" -> Some("a"), "en" -> Some("abc"), "fr" -> Some("ab"))), 
        new GT("Switch", Map("de" -> Some("abcdef"), "en" -> Some("b"), "fr" -> 
          Some("abc"), "es" -> Some("abc"))), 
        new GT("PVC", Map("de" -> Some("abc"), "en" -> Some("bc"), "fr" -> Some("abcd")))) 

Я хочу итерацию над списком gText, но зависит от ключа «имена» карты и в порядке убывания длины каждого значения карты «имена».

Первая итерация должна быть в следующем Одер со значениями для «де»:

1. code: "Switch" & names.key="de" & names.value = Some("abcdef") 
2. code: "PVC" & names.key="de" & names.value = Some("abc") 
3. code: "USB" & names.key="de" & names.value = Some("a") 

Вторая итерация должна быть в следующем Одер со значениями для «ан»:

1. code: "USB" & names.key="en" & names.value = Some("abc") 
2. code: "PVC" & names.key="en" & names.value = Some("bc") 
3. code: "Switch" & names.key="en" & names.value = Some("b") 

Третья итерация должна быть следующей: со следующими значениями для «fr»:

1. code: "PCV" & names.key="fr" & names.value = Some("abcd") 
2. code: "Switch" & names.key="fr" & names.value = Some("abc") 
3. code: "Switch" & names.key="fr" & names.value = Some("ab") 

Последнее чество для names.key="es" code="Switch" & names.key="es" и names.value = Some("abc")

Как уже упоминалось выше, основной целью является итерации значения для одной и той же тональности различные GT-х зависит от длины каждого значения.

Как это сделать. Может быть, прежде всего, мне нужно собрать ключ в дополнительном наборе, а затем отфильтровать и sortyBy. Пожалуйста, любые предложения приветствуются.

Заранее благодарен. Ugur

+0

«Как это сделать на одной итерации». - но ваш пример дает четыре итерации. Поэтому я не уверен, что вы спрашиваете. Известно ли количество и значения кодов стран заранее? –

+0

Вам не нужно использовать 'new' с классами классов –

+0

thx. Одна итерация невозможна. Я хотел знать, как выполнять итерацию только значений одного ключа, отсортированного по длине. – ugurkocak1980

ответ

1

Мне не совсем понятно, какой именно порядок итераций вы хотите, но вот еще один способ снятия шкуры кота.

val countrySet = gText.flatMap { _.names.keys }.toSet 
    for { 
    c <- countrySet 
    gc = gText.filter(_.names.contains(c)) 
    g <- gc.sortBy(_.names(c).get.length).reverse 
    } println("country " + c + " " + g) 

Получить набор стран. Затем, перебирать те, фильтровать список только те, которые имеют вход для текущей страны, сортировать этот список по л ength соответствующего значения (обратный, чтобы получить убывающую длину)

+0

Спасибо вам, Пол! – ugurkocak1980

1
val gtEntries = gText.flatMap(gt => gt.names.toList.map(entry => (gt.code, entry._1, entry._2))) 
val gtEntriesByLang = gtEntries.groupBy(_._2) 

for (lang <- gtEntriesByLang.keys.toList.sorted; 
gtEntry <- gtEntriesByLang(lang).sortBy(entry => -entry._3.map(_.length).getOrElse(0))) 
{ 
    println(gtEntry) 
} 

Первая строка 'сглаживает' список GTs в кортежи вида ("USB", "ан", Некоторые из них ("а")).

Вторая строка группирует ее по языку i. е. «en» => List ((«USB», «en», Some («abc»), ...)

Для понимания используются все языки в порядке убывания, а затем сортирует записи по длине из значений исходной карты имен (0, если параметр не определен, введите 1, если вы хотите быть отличным от «»).

+0

Thx, это идеальное решение. Я протестировал его. Замечательно – ugurkocak1980