【问题标题】:How to generic a function where params are different structs with different properties?如何通用一个函数,其中参数是具有不同属性的不同结构?
【发布时间】:2017-09-12 04:36:39
【问题描述】:

请参考以下代码:

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 的二维数组。我不知道如何根据键将反一维数组的函数泛型为二维数组?

【问题讨论】:

  • 您的最终目标是在创建的每个商店中都有一个商品列表吗?如果是,为什么不直接做struct Store { var areaName = "" var name: String = "" var items:[Item] = [] }。如果没有,您能否详细说明
  • ItemStore 之间有什么关系?此外,据我所知,在 Swift 中没有本地方法可以创建 2D 数组。您使用的是数组数组而不是二维数组。
  • 不,StoreItems 没有任何关系。仅struct 的 2 个示例,一个密钥是 Int 类型,一个密钥是 String。我得到了storesArray和itemsArray,并想根据自己的密钥转换为二维数组,但共享相同的转换逻辑@Lamar
  • 是的,我的目标是为Array编写一个扩展方法,将数组转换为数组数组(抱歉我不清楚array of array2D array的区别),基于他们自己的钥匙。我写了一个函数来解决这个问题。但是我不怎么通用,Store,关键是String,分享函数@ebby94

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


【解决方案1】:

我认为您不能为 Array 编写泛型扩展,其中元素的类型要么是 Item 要么 Store 因为它们都没有任何关系让你编写一个通用的泛型方法.您可以为 Array 编写扩展,其中元素将属于上述类型。你只需要让你的两个结构都符合 equatable 协议。

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")]]

【讨论】:

    猜你喜欢
    • 2022-12-18
    • 1970-01-01
    • 2020-02-26
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多