首页 > 解决方案 > 如何管理数组索引?

问题描述

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

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]

我想从它们的值中获取耦合数组和arraysPrice,并且我想根据正确的索引获取arrays.keys。当我尝试制作它时,arrays.keys 会出现错误的顺序。(因为它是按上面显示的顺序排列的。)有人可以帮我吗?我希望我能问清楚。

标签: iosarraysswiftxcode

解决方案


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

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)

“压缩”两个数组就是从每个数组中取出一个元素,并将它们变成一个 tuple (String, String)。然后将其传递给Item.init. 当任一数组用完时,拉链就会停止(因此,如果它们的长度不同,则可能会忽略某些项目)。此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代码非常好。


推荐阅读