16

私は次のようなアイテムの配列を持っています:

@items = [
  {price: 12, quantity:1}, 
  {price: 4, quantity:1}, 
  {price: 8, quantity:1}
]

そして、私はこのようなものを探しています:

sumPrice: ->
  @items.sum (item) -> item.price * item.quantity

または、これに可能な限り近いものであれば、コードを読んでいるすべての人が何が起こっているのかを非常に簡単に理解できます。

これまでのところ、私は思いついた:

sumPrice: ->
   (items.map (a) -> a.price * a.quantity).reduce (a, b) -> a + b
  • 機能魔法が多すぎる
  • 説明力を失う

と:

sumPrice: ->
   sum = 0
   for item in items
     sum += item.price * item.quantity
   sum
  • 初心者の JS/Coffee プログラマーが理解できる
  • 少しばかげているように感じる

私はCoffeeScriptが大好きなので、私が見逃しているこれと同様のシナリオに対するより良い解決策があることを願っています.

4

4 に答える 4

14

機能的なスタイルはそれほど悪くありません。CoffeeScript を使用すると、次のようにコードを整形できます。

items
  .map (item) ->
    item.price * item.quantity
  .reduce (x,y) ->
    x+y

このコードは、ワンライナーよりも理解しやすいです。

気に入らない場合は、代わりにmap使用できますfor。このような:

(for item in items
  item.price * item.quantity)
  .reduce (x,y)->x+y

またはこのように:

prods = for item in items
  item.price * item.quantity
prods.reduce (x,y)->x+y

sum()または、配列に独自のメソッドを追加できます。

Array::sum = -> @reduce (x,y)->x+y
(item.price * item.quantity for item in items).sum()
于 2012-12-19T12:19:35.620 に答える
13

あなたがメソッドを@items.sum (item) -> item.price * item.quantity追加することができるようにあなたが解決策を表現したいなら:sumArray

Array::sum = (fn = (x) -> x) ->
  @reduce ((a, b) -> a + fn b), 0

sum = @items.sum (item) -> item.price * item.quantity

0の初期値として渡しているreduceので、fnすべての配列値に対してコールバックが呼び出されることに注意してください。


組み込みオブジェクトを拡張したくない場合は、独自の関数で単一の配列アイテムの合計価格を計算するロジックを抽出すると、合計を単一の削減としてエレガントに表現できると思います。

itemPrice = (item) -> item.price * item.quantity

sum = items.reduce ((total, item) -> total + itemPrice item), 0
于 2012-12-19T15:14:53.850 に答える
8

分解を使用して、コードをわずかに単純化できます。

sumPrice: ->
    sum = 0
    sum += price * quantity for {price, quantity} in @items
    sum

の明示的な初期化を取り除く方法はないと思いますsum。Coffeescript のforループ構文は、そうでなければ を使用するコードを単純化するのに役立つ傾向がありますが、ここで行っている -type 操作map()を単純化する類似のものは実際にはありません。reduce()sumPrice

コメントで述べたように、このソリューションがreduce()orの呼び出しに勝る利点の 1 つsum()は、関数を作成して繰り返し呼び出すオーバーヘッドを回避できることです。

于 2012-12-19T11:14:56.227 に答える
2
sum = 0
value = (item) ->
  item.price * item.quantity
sum += value(item) for item in @items
于 2012-12-19T11:50:37.937 に答える