如何通用一个函数,其中params是具有不同属性的不同结构?

时间:2017-09-12 04:36:39

标签: arrays swift generics generic-programming swift-protocols

请参阅以下代码:

import UIKit

struct Item {
    var brandId = 1
    var name: String = ""
}
struct Store {
    var areaName = ""
    var name: String = ""
}

let itemArray = [Item(brandId: 1, name: "item1"), Item(brandId: 2, name: "item2"), Item(brandId: 1, name: "item3") ]

let storeArray = [Store(areaName: "hk", name: "store1"), Store(areaName: "bj", name: "store2"), Store(areaName: "hk", name: "store3")]


var intKeys = [Int]()
var groupedItems = [[Item]]()

var stringKeys = [String]()
var groupedStores = [[Store]]()

extension Array {

    func transTo2d() -> [[Element]] {
        let grouped = [[Element]]()

        return grouped
    }

}

itemArray.forEach { (item) in
    let brandId = item.brandId
    if !intKeys.contains(brandId) {
        intKeys.append(brandId)
        var newArray = [Item]()
        newArray.append(item)
        groupedItems.append(newArray)
    } else {
        let index = intKeys.index(of: brandId)!
        groupedItems[index].append(item)
    }
}

我的最终目标是使用itemArray.transTo2d()根据项brandId获取二维数组,使用storeArray.transTo2d()根据商店areaName获取二维数组。我不知道如何根据键将一维数组转换为二维数组的函数?

1 个答案:

答案 0 :(得分:0)

我认为你不能为数组编写通用扩展,其中元素的类型为ItemStore,因为它们都不共享任何关系一种通用的通用方法。您可以为Array编写扩展名,其中元素将是所提及的类型。您只需要将两个结构符合等效协议即可。

struct Item {
    var brandId = 1
    var name: String = ""
}

extension Item : Equatable{
    static func ==(lhs: Item, rhs: Item) -> Bool{
        return lhs.brandId == rhs.brandId
    }
}

struct Store {
    var areaName = ""
    var name: String = ""
}

extension Store : Equatable{
    static func ==(lhs: Store, rhs: Store) -> Bool{
        return lhs.areaName == rhs.areaName
    }
}

extension Array where Element == Store{
    func transform()->[[Store]]{
        var storeArray = self
        var groupedArray = [[Store]]()
        while storeArray.count > 0{
            if let firstElement = storeArray.first{
                groupedArray.append(storeArray.filter{$0.areaName == firstElement.areaName})
                storeArray = storeArray.filter{$0.areaName != firstElement.areaName}
            }
        }
        return groupedArray
    }
}

extension Array where Element == Item{
    func transform()->[[Item]]{
        var itemArray = self
        var groupedArray = [[Item]]()
        while itemArray.count > 0{
            if let firstElement = itemArray.first{
                groupedArray.append(itemArray.filter{$0.brandId == firstElement.brandId})
                itemArray = itemArray.filter{$0.brandId != firstElement.brandId}
            }
        }
        return groupedArray
    }
}

使用转换功能

let storeArray = [Store(areaName: "hk", name: "store1"), Store(areaName: "bj", name: "store2"), Store(areaName: "hk", name: "store3")]
let itemArray = [Item(brandId: 1, name: "item1"), Item(brandId: 2, name: "item2"), Item(brandId: 1, name: "item3") ]
print(storeArray.transform())
print(itemArray.transform())

这将打印出我认为你想要的输出。

[[Store(areaName: "hk", name: "store1"), Store(areaName: "hk", name: "store3")], [Store(areaName: "bj", name: "store2")]]
[[Item(brandId: 1, name: "item1"), Item(brandId: 1, name: "item3")], [Item(brandId: 2, name: "item2")]]