私はこのようなScalaコードを持っています
var i = 1
for(e <- array) {
acc += e * i
i += 1
}
配列の最初の要素に1を掛け、次の要素に2を掛け、次の要素に3を掛けて、すべてをアキュムレータに追加する必要があります。Scalaでこれを行うには、おそらく折りたたむことでさえ、より良い方法があると思いますか?
私はこのようなScalaコードを持っています
var i = 1
for(e <- array) {
acc += e * i
i += 1
}
配列の最初の要素に1を掛け、次の要素に2を掛け、次の要素に3を掛けて、すべてをアキュムレータに追加する必要があります。Scalaでこれを行うには、おそらく折りたたむことでさえ、より良い方法があると思いますか?
「より良い」はあなたの目標が何であるかに依存します。短くて明確ですか?おそらく
{ for (i <- array.indices; e = array(i)) yield (i+1)*e }.sum
また
array.indices.map(i => (i+1)*array(i)).sum
(または、途中で中間体を作成するため、少し速くなります。
array.indices.iterator.map(i => (i+1)*array(i)).sum
)。
通常、短く明確にする必要があります。
速い?次に、古い学校に行く必要があります:
var i = 0
var acc = 0
while (i < array.length) {
acc += (i+1)*array(i)
i += 1
}
または再帰を使用します
def sum(a: Array[Int], i: Int = 0, acc: Int = 0): Int =
if (i >= a.length) acc else sum(a, i+1, (i+1)*a(i) + acc)
sum(array)
私は読みやすいzipWithIndexを好みます:
array.zipWithIndex.map { case (e, i) => e * (i + 1) }.sum
val x = List(1,1,1,1,1,1)
(((0,1) /: x){case ((acc, mult), l) => (acc + (l * mult), mult + 1) })._1
つまり、アキュムレータ0と乗数1から始めて、リストの各要素を折りたたんで、アキュムレータを1に変更しacc + (l * mult)
、乗数を1ずつ増やします。最後に最後の乗数も取得するので、次のように呼び出します。._1
アキュムレータを取得するだけです。
編集:@RexKerrが以下の彼の回答(およびコメント)で指摘しているように、パフォーマンスが主要な懸念事項である場合は、明示的な再帰的方法を使用することをお勧めします。
私が提案することがより機能的であるため、それを行うためのより良い方法であるかどうかはわかりません(==パフォーマンスが遅くなります):
(0 /: (array zipWithIndex)) {(a, i) => (i._1 * (i._2 + 1)) + a}
これは、 http: //www.scala-lang.org/api/current/index.html#scala.ArrayのzipWithIndexメソッドによって生成された配列に対してfoldLeftを実行します。
zipWithIndexは、コレクションの要素とそのインデックスを単純に圧縮します。