Swift 3 Equatable结构可选函数
这会有点啰嗦,请耐心听我说。我也是一个有点敏捷的初学者。我有一个定义了结构的数组Swift 3 Equatable结构可选函数,swift,Swift,这会有点啰嗦,请耐心听我说。我也是一个有点敏捷的初学者。我有一个定义了结构的数组 var modelOriginalArray = [model]() struct model: Equatable { var modelID = String() var modelName = String() var modelNumber = String() var manufacturer
var modelOriginalArray = [model]()
struct model: Equatable {
var modelID = String()
var modelName = String()
var modelNumber = String()
var manufacturer = String()
var manufShort = String()
var phiTypeCode = String()
var phiTypeDesc = String()
init(modelID: String, modelName: String, modelNumber: String, manufacturer: String, manufShort: String, phiTypeCode: String, phiTypeDesc: String) {
self.modelID = modelID
self.modelName = modelName
self.modelNumber = modelNumber
self.manufacturer = manufacturer
self.manufShort = manufShort
self.phiTypeCode = phiTypeCode
self.phiTypeDesc = phiTypeDesc
}
static func == (lhs: model, rhs: model) -> Bool {
return lhs.manufShort == rhs.manufShort && lhs.modelName == rhs.modelName && lhs.modelNumber == rhs.modelNumber
}
}
我将大约5000条记录加载到此数组中。然后,我需要根据搜索条件筛选此数组。假设我正在寻找一家制造商“索尼”。索尼可能有多种型号,因此我需要将所有索尼唱片与更大的5000分开
srchval = "SONY"
var filteredArray = [model]()
var uniqueFilteredArray = [model]()
filteredArray = self.modelOriginalArray.filter { $0.manufShort.range(of: srchval, options: .caseInsensitive) != nil }
这将给我一个只有“索尼”唱片的阵列。但是,有些“索尼”记录可能在不同的modelID下有重复的manufShort、modelName、modelNumber值。我需要把它们分开,只有唯一的记录
// Find Uniquic options by removing duplicate Model Names
uniqueFilteredArray = unique(models: filteredArray)
func unique(models: [model]) -> [model] {
var uniqueModels = [model]()
for model in models {
if !uniqueModels.contains(model) {
uniqueModels.append(model)
}
}
return uniqueModels
}
这一切都很好。我遇到的问题是在筛选器中,在某些情况下,我必须确保记录匹配:
static func == (lhs: model, rhs: model) -> Bool {
return lhs.manufShort == rhs.manufShort && lhs.modelName == rhs.modelName && lhs.modelNumber == rhs.modelNumber
}
在同一个班级的不同情况下,我只需要在手动短距离上进行匹配:
static func == (lhs: model2, rhs: model2) -> Bool {
return lhs.manufShort == rhs.manufShort
}
我曾尝试创建一个单独的模型,即使用此不同的静态函数的model2,但我很难使用不同的结构将数据从一个数组移动到另一个数组
有什么想法或更好的方法来实现这一点
谢谢您可以在
收藏
上使用以下扩展。没有测试
extension Collection where Iterator.Element: Equatable {
func uniques(by equals: (Iterator.Element, Iterator.Element) -> Bool) -> [Iterator.Element] {
var uniqueElems: [Iterator.Element] = []
for elem in self {
if uniqueElems.index(where: { equals($0, elem) }) == nil {
uniqueElems.append(elem)
}
}
return uniqueElems
}
}
然后你可以用
filteredArray.uniques { $0.manufShort == $1.manufShort }
filteredArray.uniques { $0.manufShort == $1.manufShort && $0.modelName == $1.modelName && $0.modelNumber == $1.modelNumber }
因为使用两种不同的方法来定义两个模型的“相等”,你可能应该考虑不使用<代码>=运算符,因为如果等式谓词不同,则不真正测试相等性。相反,您有两个不同的自定义谓词(适用于两个模型实例),希望在不同的上下文中使用。为什么不为此使用两个自定义类型(静态)方法,使用描述性名称,在语义上描述它们的不同含义
谢谢!这是很有意义的,我如何调用不同的(静态)方法,以便它能够根据我所追求的内容找到正确的函数。举个例子 设置示例:struct Foo {
let id: String
let bar: Int
let baz: Int
let bax: Int
init(_ id: String, _ bar: Int, _ baz: Int, _ bax: Int)
{
self.id = id
self.bar = bar
self.baz = baz
self.bax = bax
}
static func byBarEqualityPredicate(lhs: Foo, rhs: Foo) -> Bool {
return lhs.bar == rhs.bar
}
static func byBazAndBaxEqualityPredicate(lhs: Foo, rhs: Foo) -> Bool {
return lhs.baz == rhs.baz && lhs.bax == rhs.bax
}
}
let fooArr = [Foo("Foo A", 1, 2, 3),
Foo("Foo B", 1, 1, 2),
Foo("Foo C", 3, 1, 2)]
您的unique
方法的一个稍加修改的版本,现在在foos
数组中提供了一个(Foo,Foo)->Bool
谓词:
func unique(foos: [Foo], predicate: (Foo, Foo) -> Bool) -> [Foo] {
var uniqueFoos = [Foo]()
for foo in foos {
if !uniqueFoos.contains(where: { predicate($0, foo) }) {
uniqueFoos.append(foo)
}
}
return uniqueFoos
}
使用两个不同的Foo
谓词进行测试:
// by 'bar' "equality": Foo A and Foo B will be considered "equal",
// and only Foo A, among these two , will be added to the "unique" array.
let fooWithBarPredicate = unique(foos: fooArr, predicate: Foo.byBarEqualityPredicate)
fooWithBarPredicate.forEach { print($0.id) } // Foo A, Foo C
// by 'baz' && 'bax' "equality": Foo A and Foo C will be considered "equal",
// and only Foo A, among these two, will be added to the "unique" array.
let fooWithBazBaxPredicate = unique(foos: fooArr, predicate: Foo.byBazAndBaxEqualityPredicate)
fooWithBazBaxPredicate.forEach { print($0.id) } // Foo A, Foo B
既然使用两种不同的方法来定义两个模型的“相等”,那么你可能应该考虑不使用
Foo
而不是Model
,从示例的意义上来说:)。这对我来说非常有效。我甚至可以添加第三个谓词来进行更集中的搜索。完美的解决方案。