Jeff A. Ripke
Jeff A. Ripke

Reputation: 11

Calculating subtotals and totals from a dictionary

Is there a better way to write this code, using Swift? I am using a nested for loop and I could not think of a better way to write this code. I am just a beginner trying to figure this out.

var products = [
    ["product": "soap", "price": 3.50],
    ["product": "cereal", "price": 2.56],
    ["product": "soup", "price": 3.25]
]

var shoppingCart = ["soap", "cereal"]


var count = 0
var subTotal = 0.0
for product in products {
    for cartItem in shoppingCart.enumerate() {
        if cartItem.element == products[count]["product"] {
            print(cartItem.element)
            if count <= products.count {
                count += 1
                var cost = products[count]["price"]! as! Double
                subTotal += cost
            }
        }
    }
}
let totalCost = subTotal * 1.086
print("The total cost of your shopping cart $\(totalCost).")

Upvotes: 0

Views: 268

Answers (2)

vacawama
vacawama

Reputation: 154651

If you make your products into a dictionary that maps product name to price, then you can use reduce to add up the values:

var products = [
    "soap": 3.50,
    "cereal": 2.56,
    "soup": 3.25
]

var shoppingCart = ["soap", "cereal"]

let totalCost = 1.086 * shoppingCart.reduce(0.0, combine: { $0 + (products[$1] ?? 0) })

Notes:

  1. Reduce starts with an initial value 0.0 and adds the value of each of the products as it finds them. $0 is the running total, and $1 holds each of the values in the shopping cart in turn.
  2. If you have a product in your cart that doesn't have a listed price, then the dictionary look up will return nil. The nil coalescing operator ?? is used here to safely unwrap the value returned from the dictionary and use a default price of 0 if the product isn't found.

Upvotes: 2

Said Sikira
Said Sikira

Reputation: 4533

I think that your dictionaries structure is not very good for the result you want to achieve. Since you didn't wrote that you must use dictionaries, I have used native Swift classes and structures to achieve the result you need. It's much easier to test, maintain and use in the long run.

First define Product class:

class Product {
    let name: String
    let price: Double

    init(name: String, price: Double) {
        self.name = name
        self.price = price
    }
}

Now create instances of your product:

let soap = Product(name: "Soap", price: 3.5)
let cereal = Product(name: "Cereal", price: 2.56)
let soup = Product(name: "Soup", price: 3.25)

And the shopping cart (two soaps and one cereal package):

var shoppingCart = [soap, soap, cereal]

You would get a count by running this:

let count = shoppingCart.count // returns 3

And the subtotal with this:

var subTotal = shoppingCart.reduce(0.0, combine: {$0 + $1.price})
// Would return 9.56

Note that I'm using reduce functional method on array, to make the computation short as possible, but you could also loop through shopping cart and get the same result.

Upvotes: 2

Related Questions