功能和选项练习

时间:2017-07-23 04:46:56

标签: swift dictionary

我是Swift的新手。最近,我正在进行Swift练习。

想象一下,您正在创建一个用于购物的应用。编写一个函数,该函数将采用要购买的项目的名称,并将返回该项目的成本。在该功能的正文中,通过在字典库存中访问该项目来检查该项目是否有库存。如果是,则通过在字典价格中访问该项目的价格来返回该项目的价格。如果该商品缺货,请返回零。调用该函数并传入下面的字典中存在的String。打印返回值。

var prices = ["Chips": 2.99, "Donuts": 1.89, "Juice": 3.99, "Apple": 0.50, "Banana": 0.25, "Broccoli": 0.99]
var stock = ["Chips": 4, "Donuts": 0, "Juice": 12, "Apple": 6, "Banana": 6, "Broccoli": 3]

func purchase(prices:String)->(Int?){
    if stock.index(forKey: prices) == nil{
        return nil
    }else{
        for (String,value) in prices{
            return value
        }
    }
}

我尝试访问股票字典,但我不知道如何返回给定字符串的结果。

错误是:

  

type'String'不符合协议'Sequence'。

2 个答案:

答案 0 :(得分:0)

你这样做完全错了。我建议你先了解基础知识。该要求可以通过以下方式满足

func purchase(item:String)->Double?{
    if let price = prices[item] {
        if let quantity = stock[item] { // check for quantitiy of item
            if quantity == 0 { // item present but 0 quantatiy
                return nil
            }
        } else {
            return nil // item not present in stock
        }
        stock[item] = stock[item]! - 1 // one itme sold
        return price // return the price of the item

    } else {
        return nil // item not present in prices
    }
}

答案 1 :(得分:0)

为了更加简洁(虽然以简洁为代价)接近:

var prices = ["Chips": 2.99, "Donuts": 1.89, "Juice": 3.99, "Apple": 0.50, "Banana": 0.25, "Broccoli": 0.99]
var stock = ["Chips": 4, "Donuts": 0, "Juice": 12, "Apple": 6, "Banana": 6, "Broccoli": 3]

func purchase(item: String) -> Double? {
    // item is in stock with a quantity larger than 0
    guard (stock[item] ?? 0) > 0 else { return nil }

    // return the price for the item (which is in stock), at
    // the same time decreasing the stock of the item by 1.
    return prices[item].map { stock[item]? -= 1; return $0 }
}

使用示例:

print(stock["Chips"] ?? 0)
purchase(item: "Chips") // 2.99
print(stock["Chips"] ?? 0) // 3
purchase(item: "Chips") // 2.99
purchase(item: "Chips") // 2.99
purchase(item: "Chips") // 2.99
print(stock["Chips"] ?? 0) // 0
purchase(item: "Chips") // nil (out of stock!)
print(stock["Chips"] ?? 0) // 0

但是,由于pricesstock属性紧密相连,而且在编译时已知不同的项类型,您可能需要考虑使用自定义数据结构来表示价格和给定项目的库存。例如。符合Hashable的符号,以便您的商品可以在Set集合中展示。此外,在简单商店的情况下,每个项目应该是唯一可识别的,因此使用enum来识别这样的项目是合理的。 E.g:

enum ItemIdentifier: Int {
    case chips, donuts, juice, apple, banana, broccoli
}

// we design items to be unique, and want (in this simple example)
// to allow updating their properties on-the-fly via subscripting,
// so we design them as reference (class) type.
class Item : Hashable {
    let itemIdentifier: ItemIdentifier
    var price: Double
    var stock: Int

    init(_ itemIdentifier: ItemIdentifier, _ price: Double, _ stock: Int) {
        self.itemIdentifier = itemIdentifier
        self.price = price
        self.stock = stock
    }

    // OBS!
    // generally we'd like to define equalness as all-instance-member equality,
    // but since items, in this example, are designed to be unique, we will only
    // define the equalness of two items as the equalness of their itemIdentifier.
    static func ==(lhs: Item, rhs: Item) -> Bool {
        return lhs.itemIdentifier == rhs.itemIdentifier
    }

    var hashValue: Int {
        return itemIdentifier.rawValue
    }
}

在这种情况下,您的商品商店(例如Store)拥有Set个(唯一)商品,当商品被购买或重新库存(或重新定价)时,这些商品可能会发生变异:

struct Store {
    private var items: Set<Item>
    init() {
        items = Set([Item(.chips,    2.99, 4),
                     Item(.donuts,   1.89, 0),
                     Item(.juice,    3.99, 12),
                     Item(.apple,    0.50, 6),
                     Item(.banana,   0.25, 6),
                     Item(.broccoli, 0.99, 3)])
    }

    subscript(itemIdentifier: ItemIdentifier) -> Item? {
        get {
            let dummy = Item(itemIdentifier, 0.0, 0)
            return items.index(of: dummy).map { items[$0] }
        }
    }

    // ... methods/subscript to add new or update/replace existing items

    func purchase(item itemIdentifier: ItemIdentifier) -> Double? {

        // item is in stock with a quantity larger than 0
        guard (self[itemIdentifier]?.stock ?? 0) > 0 else { return nil }

        // return the price for the item (which is in stock), at
        // the same time decreasing the stock of the item by 1.
        return self[itemIdentifier].map { $0.stock -= 1; return $0.price }
    }
}

使用示例:

var store = Store()

print(store[.broccoli]?.stock ?? 0) // 3
store.purchase(item: .broccoli) // 0.99
print(store[.broccoli]?.stock ?? 0) // 2
store.purchase(item: .broccoli) // 0.99
store.purchase(item: .broccoli) // 0.99
print(store[.broccoli]?.stock ?? 0) // 0
store.purchase(item: .broccoli) // nil
store[.broccoli]?.stock += 1