Ответ 1
b map Function.tupled((num, i) => if(num > 8) num else i)
избегает сопоставления шаблонов и для-выражений, поэтому должно быть достаточно эффективным. Обычно я использовал бы case
, как вы это делали.
Мне нравится, когда мой код довольно наивно читаем.
Если я настрою простой список кортежей:
scala> val a = List(6, 8, 10)
a: List[Int] = List(6, 8, 10)
scala> val b = a zipWithIndex
b: List[(Int, Int)] = List((6,0), (8,1), (10,2))
Я хотел бы сопоставить() в списке, но я нахожу синтаксис._1._2 немного трудночитаемым:
scala> val c = b map ( a => if(a._1 > 8) a._1 else a._2 )
c: List[Int] = List(0, 1, 10)
Чтобы "называть" кортеж, я использовал:
scala> val c = b map ( { case (num, i) => if(num > 8) num else i } )
c: List[Int] = List(0, 1, 10)
Два вопроса:
1) Есть ли более сжатый способ назвать члены кортежа?
2) Есть ли значительный успех для моей версии выше (она используется в умеренно критическом для производительности коде).
Спасибо.
b map Function.tupled((num, i) => if(num > 8) num else i)
избегает сопоставления шаблонов и для-выражений, поэтому должно быть достаточно эффективным. Обычно я использовал бы case
, как вы это делали.
В этом случае вы можете найти эквивалентный синтаксис для понимания понятным, но это действительно вопрос вкуса...
for {(num, i) <- b} yield if(num >8) num else i
FWIW, я попытался сопоставить карту с сопоставлением с шаблоном и без него, и я получил почти то же время выполнения.
Код, который я использовал:
object bench extends scala.testing.Benchmark {
var b:List[(Int, Int)] = _
override def setUp {
val a = (1000000 to 2000000).toList
b = a zipWithIndex
}
def run = b map ( a => if(a._1 > 8) a._1 else a._2 )
}
Я также создал другое приложение с объектом bench1
, которое имеет только версию карты с совпадением шаблонов вместо ._1
и ._2
.
Результаты моего старого нетбука (scala 2.9.1, xubuntu 11.10):
$ scala bench 10
bench$ 750 758 731 721 733 736 725 743 735 736
$ scala bench1 10
bench1$ 774 772 740 724 745 730 711 739 740 740