如何将具有多个参数的数组分组

时间:2018-06-28 07:49:21

标签: ios swift

我有一个如下数组:

let arr = [InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None"),
       InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None"),
       InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None"),
       InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None"),
       InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None"),
       InventoryItem(capacity: "1/2T", chainLength: 65, speed: "16FPM", voltage: "208V", frameSize: "Standard", controlStation: "Integrated"),
       InventoryItem(capacity: "1/2T", chainLength: 65, speed: "16FPM", voltage: "208V", frameSize: "Standard", controlStation: "Integrated"),
       InventoryItem(capacity: "1/2T", chainLength: 65, speed: "16FPM", voltage: "208V", frameSize: "Standard", controlStation: "Integrated"),
       InventoryItem(capacity: "1/2T", chainLength: 65, speed: "16FPM", voltage: "208V", frameSize: "Standard", controlStation: "Integrated")]

我想将它们分组到所有元素都具有相同属性的其他数组或字典中。有办法吗?

2 个答案:

答案 0 :(得分:3)

您可以通过使InventoryItem符合EquatableHashable来采用此示例,

class InventoryItem: Equatable, Hashable {

    var hashValue: Int { return a.hashValue ^ b.hashValue ^ c.hashValue }

    static func == (lhs: InventoryItem, rhs: InventoryItem) -> Bool {
        return  lhs.a == rhs.a &&
                lhs.b == rhs.b &&
                lhs.c == rhs.c
    }

    var a: String
    var b: String
    var c: String

    init(_ a: String, b: String, c: String) {
        self.a = a
        self.b = b
        self.c = c
    }
}

让我们说我们有这个数据,

let inv1 = InventoryItem("a", b: "b", c: "c")
let inv2 = InventoryItem("a", b: "b", c: "c")
let inv3 = InventoryItem("p", b: "q", c: "r")
let inv4 = InventoryItem("x", b: "y", c: "z")
let list = [inv1, inv2, inv3, inv4]

var groupedItems: [String: [InventoryItem]] = [:]

let unique = Set(list)
unique.forEach { (item) in
   groupedItems["\(item.hashValue)"] = list.filter({ $0 == item })
}

groupedItems.keys.forEach { key in
   let items = groupedItems[key]!
   print(items.count)
   items.forEach({ (item) in
       print("\(item.a)\(item.b)\(item.c)")
   })
}

输出:

1
xyz
1
pqr
2
abc
abc

注意:如果您的InventoryItemstructenum,则无需明确符合Equatable,只需符合Hashable就足够了,您只需从hashValue中删除static func == (lhs: InventoryItem, rhs: InventoryItem) -> Bool和赤道方法(InventoryItem)。

答案 1 :(得分:0)

您可以尝试这样的事情:

struct InventoryItem: Equatable {

    var capacity: String
    var chainLength: Int
    var speed: String
    var voltage:  String
    var frameSize: String
    var controlStation: String

    static func ==(lhs: InventoryItem, rhs: InventoryItem) -> Bool {
        return
            lhs.capacity == rhs.capacity &&
            lhs.chainLength == rhs.chainLength &&
            lhs.speed == rhs.speed &&
            lhs.voltage == rhs.voltage &&
            lhs.frameSize == rhs.frameSize &&
            lhs.controlStation == rhs.controlStation

    }
}

let arr = [InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None"),
           InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None"),
           InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None"),
           InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None"),
           InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None"),
           InventoryItem(capacity: "1/2T", chainLength: 65, speed: "16FPM", voltage: "208V", frameSize: "Standard", controlStation: "Integrated"),
           InventoryItem(capacity: "1/2T", chainLength: 65, speed: "16FPM", voltage: "208V", frameSize: "Standard", controlStation: "Integrated"),
           InventoryItem(capacity: "1/2T", chainLength: 65, speed: "16FPM", voltage: "208V", frameSize: "Standard", controlStation: "Integrated"),
           InventoryItem(capacity: "1/2T", chainLength: 65, speed: "16FPM", voltage: "208V", frameSize: "Standard", controlStation: "Integrated")]

let newArr = arr.filter { (obj) -> Bool in
    return obj == InventoryItem(capacity: "1T", chainLength: 55, speed: "32FPM", voltage: "110V", frameSize: "Small", controlStation: "None")
}