如何管理数组索引?

时间:2019-09-26 12:53:38

标签: ios arrays swift xcode

我关于数组的问题。我有数组:

var orderItemName = [String]()

["halimiz duman aman", "halimiz duman aman", "halimiz duman aman", "halimiz duman aman", "halimiz duman aman", "halimiz duman aman", "burada da urun var", "burada da urun var", "burada da urun var", "urunler burdadir", "urunler burdadir", "urunler burdadir", "urunler burdadir", "urunler burdadir"]

var orderItemPrice = [String]()

["14 ₺", "14 ₺", "14 ₺", "14 ₺", "14 ₺", "14 ₺", "425 ₺", "425 ₺", "425 ₺", "32 ₺", "32 ₺", "32 ₺", "32 ₺", "32 ₺"]

var arrays = [String: Int]() 

["halimiz duman aman": 6, "urunler burdadir": 5, "burada da urun var": 3]

var arraysPrice = [String: Int]()

["425 ₺": 3, "14 ₺": 6, "32 ₺": 5]

我想从它们的值中获取耦合的array和arraysPrice,我想根据正确的索引获取arrays.keys。当我尝试使其arrays.keys将出现错误的顺序。 (因为它是按照上面显示的顺序排列的。)有人可以帮助我吗?我希望我可以清楚地问。

1 个答案:

答案 0 :(得分:2)

转换为结构。否则,它将继续咬你。

struct Item {
    let name: String
    let price: String // Should be a Currency type, but matching your code
}

let items = [
    Item(name: "halimiz duman aman", price: "14 ₺"),
    Item(name: "halimiz duman aman", price: "14 ₺"),
    Item(name: "halimiz duman aman", price: "14 ₺"),
    Item(name: "halimiz duman aman", price: "14 ₺"),
    Item(name: "halimiz duman aman", price: "14 ₺"),
    Item(name: "halimiz duman aman", price: "14 ₺"),
    ...
    ]

如果您碰巧有两个数组(我会避免创建它们,但是如果您从诸如服务器响应之类的其他东西中获取它们),则可以通过“压缩”将它们转换为结构:

let orders = zip(orderItemName, orderItemPrice).map(Item.init)

要“压缩”两个数组,则是从每个数组中取出一项,并使其成为元组(String, String)。然后将其传递到Item.init。当任何一个阵列用完时,zip都会停止(因此,如果长度不同,则某些项目可能会被忽略)。此map代码在逻辑上与以下代码相同:

var orders: [Item] = []
for (name, price) in zip(orderItemName, orderItemPrice) {
    orders.append(Item(name: name, price: price))
}

有了它,您可以计算出所需的计数。例如:

func count(name: String, in items: [Item]) {
    return items.filter(where: { $0.name == name }).count
}

您可以通过一次计算所有名称来创建所需的特定词典。

func nameCounts(from items: [Item]) -> [String: Int] {
    var result: [String: Int] = [:]

    for item in items {
        result[item.name, default: 0] += 1
    }

    return result
}

或更花哨的方式:

func nameCounts(from items: [Item]) -> [String: Int] {
    return items.reduce(into: [:]) { $0[$1.name, default: 0] += 1 }
}

这里的关键课是,您应该将与单个事物相关的所有数据放入一个结构中,然后具有这些结构的数组。不要将其散布在多个阵列上。


对于将来的学习(对于您所在的位置而言,这可能太高级了),可以使上述内容非常通用:

extension Sequence  {
    func counts<Value: Hashable>(of keyPath: KeyPath<Element, Value>) -> [Value: Int] {
        return self.reduce(into: [:]) { $0[$1[keyPath: keyPath], default: 0] += 1 }
    }
}

这允许您执行以下操作:

items.counts(of: \.name)
items.counts(of: \.price)

但是,在开始时,您不必为这种通用代码担心太多。第一个for...in代码非常好。