2015-09-30 4 views
3
case class TargetClass(key: Any, value: Number, lowerBound: Double, upperBound: Double) 

val keys: List[Any] = List("key1", "key2", "key3") 
val values: List[Number] = List(1,2,3); 
val lowerBounds: List[Double] = List(0.1, 0.2, 0.3) 
val upperBounds: List[Double] = List(0.5, 0.6, 0.7) 

Теперь я хочу построить List[TargetClass] для хранения 4 списков. Кто-нибудь знает, как сделать это эффективно? Использует for-loop для добавления элементов один за другим очень неэффективно?Как извлечь элементы из 4 списков в scala?

Я попытался использовать zipped, но, похоже, это применимо только для объединения до 3 списков.

спасибо!

+1

Кстати, пожалуйста, исправить синтаксис для списков. '{...}' не работает, вы должны использовать 'List (...)' вместо – Prashant

ответ

2

Один из подходов:

keys.zipWithIndex.map { 
    case (item,i)=> TargetClass(item,values(i),lowerBounds(i),upperBounds(i)) 
} 

Вы можете рассмотреть вопрос об использовании метода lift иметь дело со случаем списков, находящихся в разных длинах (и, таким образом, обеспечивает по умолчанию, если ключи больше, чем любой из списков?)

Я понимаю, что это не касается вашего вопроса об эффективности. Вы могли бы довольно легко выполнить некоторые тесты на разных подходах.

+0

Гораздо более читаемый подход, чем мой. +1 – Prashant

+0

Спасибо, я попробовал это, и он работает хорошо! – DarkZero

+1

К сожалению, представленные варианты, это наиболее неэффективно: | Выполняя некоторые базовые тесты по некоторым ответам, и в порядке наименьшей скорости, я обнаружил: 1) zip-zip-zip-map (@ dk14 и @prashant); за которым следует 2) транспонирование-карта (@ srgfed01); затем небольшой промежуток до 3) для-транспозиции-доходности (@ The-Archetypal-Paul), следовавший на некотором расстоянии (4) zipWithIndex. Интересно! – wwkudu

0

Я думаю, что независимо от того, что вы используете с точки зрения эффективности, вам придется проходить по спискам индивидуально. Вопрос только в том, что вы делаете это ИЛИ ради удобочитаемости, вы используете идиомы Scala и позволяете Scala делать грязную работу для вы :)?

Другие подходы не обязательно более эффективны. Вы можете изменить порядок zipping и порядок сборки возвращаемого значения функции map по своему усмотрению.

Вот более функциональный способ но я не уверен, что это будет более эффективным. См комментарии на @wwkudu (почтовый индекс) с ответом

val res1 = keys zip lowerBounds zip values zip upperBounds 
res1.map { 
    x=> (x._1._1._1,x._1._1._2, x._1._2, x._2) 
    //Of course, you can return an instance of TargetClass 
    //here instead of the touple I am returning. 
} 

Мне интересно, почему вам нужно «TargetClass»? Работает ли кортеж?

+0

Кортеж работает, но я думаю, что TagetClass гораздо читабельнее. Я не хочу, чтобы в моем коде было много «_1» _3, так как это будет прочитано другими. – DarkZero

+0

ОК. Ваш код, ваш выбор :). Удачи. – Prashant

2

Вы можете применить на молнии для первых двух списков, в последние два списков, то по результатам предыдущих молний, ​​а затем карта к классу, например, так:

val z12 = (keys, values).zipped 
val z34 = (lowerBounds, upperBounds).zipped 

val z1234 = (z12.toList, z34.toList).zipped 

val targs = z1234.map { case ((k,v),(l,u)) => TargetClass(k,v,l,u) } 

// targs = List(TargetClass(key1,1,0.1,0.5), TargetClass(key2,2,0.2,0.6), TargetClass(key3,3,0.3,0.7)) 
2

Было бы хорошо, если бы .transpose работал над кортежем списков.

for (List(k, v:Number, l:Double, u:Double) <- 
     List(keys, values, lowerBounds, upperBounds).transpose) 
    yield TargetClass(k,v,l,u) 
2

Как насчет:

keys zip values zip lowerBounds zip upperBounds map { 
    case (((k, v), l), u) => TargetClass(k, v, l, u) 
} 

Пример:

scala> val zipped = keys zip values zip lowerBounds zip upperBounds 
zipped: List[(((Any, Number), Double), Double)] = List((((key1,1),0.1),0.5), (((key2,2),0.2),0.6), (((key3,3),0.3),0.7)) 

scala> zipped map { case (((k, v), l), u) => TargetClass(k, v, l, u) } 
res6: List[TargetClass] = List(TargetClass(key1,1,0.1,0.5), TargetClass(key2,2,0.2,0.6), TargetClass(key3,3,0.3,0.7)) 
Смежные вопросы