Лучший способ выиграть и суммировать в Scala?

Есть ли лучший способ сделать это:

val totalScore = set.foldLeft(0)( _ + score(_) )

или это:

val totalScore = set.toSeq.map(score(_)).sum

Я думаю, что это - вполне общая операция, так ожидал что-то более гладкое как:

val totalScore = set.sum( score(_) )
9
задан adam77 19 January 2011 в 21:50
поделиться

4 ответа

Что ж, есть альтернативные способы записать это:

val totalScore = set.toSeq.map(score(_)).sum
val totalScore = set.toSeq.map(score).sum
val totalScore = set.toSeq map score sum

Последний может потребовать точку с запятой в конце, если следующая строка не начинается с ключевого слова. Можно также использовать .view вместо .toSeq , что позволит избежать выделения временной коллекции. Однако я не уверен, что текущее поведение .view (показ повторяющихся элементов) является правильным.

17
ответ дан 4 December 2019 в 08:50
поделиться

Проще:

scala> val is1 = Set(1, 4, 9, 16)
is1: scala.collection.immutable.Set[Int] = Set(1, 4, 9, 16)
scala> is1.reduceLeft(_ + _)
res0: Int = 30

С вашим методом оценки:

scoreSet.reduceLeft(_ + score(_))

Предупреждение, однако, это не удается, если сокращаемая коллекция пуста, а свертка - нет:

scala> val is0 = Set[Int]()
is0: scala.collection.immutable.Set[Int] = Set()

scala> is0.foldLeft(0)(_ + _)
res1: Int = 0
1
ответ дан 4 December 2019 в 08:50
поделиться

Seq.sum не принимает функцию, которую можно было бы использовать для подсчета суммы. Вы могли бы определить неявное преобразование, которое "пимпает" Traversable:

implicit def traversableWithSum[A](t: Traversable[A])(implicit m: Numeric[A]) = new {
  def sumWith(f: A => A) = t.foldLeft(m.zero)((a, b) => m.plus(a, f(b)))
}

def score(i: Int) = i + 1

val s = Set(1, 2, 3)

val totalScore = s.sumWith(score _)
println(totalScore)
=> 9

Обратите внимание, что признак Numeric существует только в Scala 2.8.

5
ответ дан 4 December 2019 в 08:50
поделиться

В качестве альтернативы, перегрузка Seq # sum , которая принимает неявное преобразование в Numeric , может использоваться, если тип в коллекции должен быть оценен / суммирован сам по себе не имеет оператора сложения. Однако, поскольку это неявный параметр преобразования, он не будет применяться, если только это не потребуется для проверки типа сокращения закрытия.

1
ответ дан 4 December 2019 в 08:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: