2012-12-19 30 views
14

tôi có một loạt các mặt hàng như sau:nhã làm một tổng của đối tượng thuộc tính trong CoffeeScript

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

Và tôi đang tìm kiếm một cái gì đó như thế này:

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

Hoặc bất cứ điều gì càng gần càng tốt với điều này, điều này khiến mọi người dễ đọc mã để hiểu điều gì đang xảy ra.

Cho đến nay tôi đã đưa ra:

sumPrice: -> 
    (items.map (a) -> a.price * a.quantity).reduce (a, b) -> a + b 
  • chứa quá nhiều chức năng kỳ diệu
  • mất descriptiveness

Và:

sumPrice: -> 
    sum = 0 
    for item in items 
    sum += item.price * item.quantity 
    sum 
  • có thể được hiểu bởi người mới lập trình viên JS/Cà phê
  • cảm thấy một chút ngu ngốc

Tôi yêu CoffeeScript vì vậy tôi hy vọng có một giải pháp tốt hơn với này & kịch bản tương tự mà tôi bỏ lỡ.

Trả lời

11

Nếu bạn muốn thể hiện các giải pháp như @items.sum (item) -> item.price * item.quantity bạn có thể thêm phương thức sum vào Array:

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

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

Lưu ý rằng tôi đang chuyển 0 làm giá trị ban đầu của reduce để gọi lại fn được gọi cho mọi giá trị mảng.


Nếu bạn không thích mở rộng các đối tượng dựng sẵn, tôi đoán bạn có thể thể hiện số tiền dưới dạng đĩa đơn giảm thanh lịch nếu bạn trích xuất các logic của tính tổng giá cho một mục mảng duy nhất trong chức năng riêng của nó:

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

sum = items.reduce ((total, item) -> total + itemPrice item), 0 
+0

Cảm ơn bạn đã thực hiện tổng! – hakunin

+1

@hakunin Bạn được chào đón. BTW, tôi quên đề cập đến rằng 'tổng hợp' có chức năng nhận dạng như tham số mặc định để bạn có thể tổng hợp một danh sách các số dễ dàng' [3, -4, 5] .sum() ':) – epidemian

+0

Tôi thích" hàm được đặt tên "Cách tiếp cận, làm cho mã này sạch hơn và tự tài liệu hơn một đống lớn các cuộc gọi lại. Tôi có thể đi thêm một bước nữa và thêm một bước nữa để tôi có thể 'sumPrices = (t, i) -> t + itemPrice (i); sum = items.reduce (sumPrices, 0) '. –

7

Bạn có thể sử dụng destructuring để đơn giản hóa mã hơi:

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

Tôi không nghĩ rằng có cách nào để thoát khỏi sự khởi rõ ràng của sum. Trong khi cú pháp vòng lặp for của Coffeescript có xu hướng giúp đơn giản hóa mã mà nếu không sẽ sử dụng map(), nó không thực sự có bất kỳ điều gì tương tự đơn giản hoá hoạt động reduce()-loại, đó là những gì sumPrice đang làm ở đây.

Như đã đề cập trong các nhận xét, một lợi thế mà giải pháp này có trên một cuộc gọi đến reduce() hoặc sum() là nó tránh được việc tạo và gọi liên tục chức năng.

+3

Bên cạnh khả năng đọc, lý do khác mà tôi tin rằng câu trả lời này là ưu việt đối với những chức năng là biên dịch này trở nên đơn giản cho bộ nhớ nhanh hơn và tốt hơn trên bộ nhớ. Nó có thể không quan trọng cho tình hình của bạn, nhưng cá nhân tôi thấy nó thậm chí còn dễ đọc hơn đối với tôi, đó là điều tốt nhất của cả hai thế giới. –

2
sum = 0 
value = (item) -> 
    item.price * item.quantity 
sum += value(item) for item in @items 
12

Kiểu chức năng không quá tệ. CoffeeScript cho phép bạn prettify mã của bạn như thế này:

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

Mã này dễ hiểu hơn so với một lớp lót của bạn.

Nếu bạn không thích map, bạn có thể sử dụng for để thay thế.Như thế này:

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

Hoặc như thế này:

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

Hoặc bạn có thể thêm phương pháp sum() của riêng bạn cho các mảng:

Array::sum = -> @reduce (x,y)->x+y 
(item.price * item.quantity for item in items).sum() 
+0

Chức năng thụt đầu dòng chức năng có vẻ tốt. Tôi nghĩ rằng tôi đang giữ cái câm mặc dù. Nếu không có ai đến với cách đẹp hơn để viết nó cho đến ngày mai, tôi chấp nhận câu trả lời của bạn, cảm ơn! – hakunin

+0

Đó là TẤT CẢ VỀ cái cuối cùng ... '[1,2,3,4] .sum() ## -> 10' –

Các vấn đề liên quan