Swift 从结构数组中删除结构数组

Swift 从结构数组中删除结构数组,swift,Swift,我有一个结构数组,如下所示: struct minStruct { var namn:String? var imag:UIImage? var rea:String? var comp:String? structArr = [minStruct(namn: "Name", imag: UIImage(named: "Image"), rea: "Something", comp: "Something"), minStruct(namn: "secondName", imag: UIIm

我有一个结构数组,如下所示:

struct minStruct {

var namn:String?
var imag:UIImage?
var rea:String?
var comp:String?
structArr = [minStruct(namn: "Name", imag: UIImage(named: "Image"), rea: "Something", comp: "Something"), minStruct(namn: "secondName", imag: UIImage(named: "secondImage"), rea: "Something2", comp: "Something2"), minStruct(namn: "thirdName", imag: UIImage(named: "thirdImage"), rea: "Something3", comp: "Something3")]

var arrToDelete = [minStruct(namn: "Name", imag: UIImage(named: "Image"), rea: "Something", comp: "Something"), minStruct(namn: "secondName", imag: UIImage(named: "secondImage"), rea: "Something2", comp: "Something2")]
}

如果我想从该数组中删除特定结构,我可以简单地执行以下操作:

var oneStruct = minStruct(namn: "Name", imag: UIImage(named: "Image"), rea: "Something", comp: "Something")

if structArr.filter({$0.namn == oneStruct!.namn}).count > 0 {

structArr = structArr.filter({$0.namn != oneStruct!.namn})
}

但是,我想做的是从structar中删除一个结构数组。大概是这样的:

struct minStruct {

var namn:String?
var imag:UIImage?
var rea:String?
var comp:String?
structArr = [minStruct(namn: "Name", imag: UIImage(named: "Image"), rea: "Something", comp: "Something"), minStruct(namn: "secondName", imag: UIImage(named: "secondImage"), rea: "Something2", comp: "Something2"), minStruct(namn: "thirdName", imag: UIImage(named: "thirdImage"), rea: "Something3", comp: "Something3")]

var arrToDelete = [minStruct(namn: "Name", imag: UIImage(named: "Image"), rea: "Something", comp: "Something"), minStruct(namn: "secondName", imag: UIImage(named: "secondImage"), rea: "Something2", comp: "Something2")]
所以我想做的是从arrstuct中删除arrtodelet内部的所有项。在本例中,arrToDelete包含structArr包含的三个结构中的两个。我想删除这两个结构并保留arrToDelete不包含的一个结构。我希望我足够清楚

散列 所以我们有了struct。首先,让我们将其设置为可散列的

struct Element: Hashable {
    var name: String?
    var image: UIImage?
    var rea: String?
    var comp: String?
    var hashValue: Int { return name?.hashValue ?? image?.hashValue ?? rea.hashValue ?? comp.hashValue ?? 0 }
}

func ==(left:Element, right:Element) -> Bool {
    return left.name == right.name && left.image == right.image && left.rea == right.rea && left.comp == right.comp
}
资料 接下来是这两个数组

let elms : [Element] = [
    Element(name:"a", image:nil, rea:nil, comp:nil),
    Element(name:"b", image:nil, rea:nil, comp:nil),
    Element(name:"c", image:nil, rea:nil, comp:nil)
]

let shouldBeRemoved: [Element] = [
    Element(name:"b", image:nil, rea:nil, comp:nil),
    Element(name:"c", image:nil, rea:nil, comp:nil)
]
解决方案#1 如果您不关心原始排序,可以使用

let filtered = Array(Set(elms).subtract(shouldBeRemoved))
解决方案#2 如果您不关心原始排序

let shouldBeRemovedSet = Set(shouldBeRemoved)
let filtered = elms.filter { !shouldBeRemovedSet.contains($0) }
我为什么不写这个?

let filtered = elms.filter { !shouldBeRemoved.contains($0) }
上面这一行是正确的解决方案。但是,调用
时包含
阵列
通常较慢(通常需要执行n/2次检查) 而不是在
集合
上调用它(通常是一次检查)

散列 所以我们有了struct。首先,让我们将其设置为可散列的

struct Element: Hashable {
    var name: String?
    var image: UIImage?
    var rea: String?
    var comp: String?
    var hashValue: Int { return name?.hashValue ?? image?.hashValue ?? rea.hashValue ?? comp.hashValue ?? 0 }
}

func ==(left:Element, right:Element) -> Bool {
    return left.name == right.name && left.image == right.image && left.rea == right.rea && left.comp == right.comp
}
资料 接下来是这两个数组

let elms : [Element] = [
    Element(name:"a", image:nil, rea:nil, comp:nil),
    Element(name:"b", image:nil, rea:nil, comp:nil),
    Element(name:"c", image:nil, rea:nil, comp:nil)
]

let shouldBeRemoved: [Element] = [
    Element(name:"b", image:nil, rea:nil, comp:nil),
    Element(name:"c", image:nil, rea:nil, comp:nil)
]
解决方案#1 如果您不关心原始排序,可以使用

let filtered = Array(Set(elms).subtract(shouldBeRemoved))
解决方案#2 如果您不关心原始排序

let shouldBeRemovedSet = Set(shouldBeRemoved)
let filtered = elms.filter { !shouldBeRemovedSet.contains($0) }
我为什么不写这个?

let filtered = elms.filter { !shouldBeRemoved.contains($0) }
上面这一行是正确的解决方案。但是,调用
时包含
阵列
通常较慢(通常需要执行n/2次检查) 而不是在
集合
上调用它(通常是一次检查)


由于某些原因,不允许使用布尔逻辑对结构进行比较,因此甚至很难在结构数组中搜索项或项的索引。例如,如果要在结构数组中搜索特定结构,然后将其删除:

首先,您需要转到struct文件并为其提供一个协议,该协议允许在
boolean
逻辑中使用struct,因此

struct Persons: Equatable {
      struct properties...
       struct init....
      }
然后可以使用数组方法在数组中搜索,例如

firstIndex(of: theStructYourLookingFor)
lastIndex(of: _)
或任何其他与布尔值相关的数组方法


从Swift 4.0及更高版本来看,这可能是新的——2019年4月

由于某些原因,不允许使用布尔逻辑对结构进行比较,因此甚至很难在结构数组中搜索项或项的索引。例如,如果要在结构数组中搜索特定结构,然后将其删除:

首先,您需要转到struct文件并为其提供一个协议,该协议允许在
boolean
逻辑中使用struct,因此

struct Persons: Equatable {
      struct properties...
       struct init....
      }
然后可以使用数组方法在数组中搜索,例如

firstIndex(of: theStructYourLookingFor)
lastIndex(of: _)
或任何其他与布尔值相关的数组方法


从斯威夫特4.0及更高版本开始,这可能是新的——2019年4月

您是斯威夫特的新手吗?是的,我忘了提到这一点,很抱歉不清楚,如果您想让我解释什么,请告诉我:)您是斯威夫特的新手吗?是的,我忘了提到这一点,很抱歉不清楚,如果您想让我解释什么,请告诉我:)它只在我尝试使其平衡时给我一条错误消息;“类型minStruct不符合协议Equatable”。我做错了什么?@MarkusJohansson:你必须定义
==
函数。再看一下我的第一块代码请注意,
Hashable
协议需要
equalable
,因此您只需遵守
Hashable
;)@原文作者2:绝对正确。非常感谢。我更新了我的答案。一般来说,这是一个很好的解决方案,但是哈希函数可以改进。现在,你可以有两个结构,它们的
namn
是相同的,但是其他值是不同的,hash等于;“类型minStruct不符合协议Equatable”。我做错了什么?@MarkusJohansson:你必须定义
==
函数。再看一下我的第一块代码请注意,
Hashable
协议需要
equalable
,因此您只需遵守
Hashable
;)@原文作者2:绝对正确。非常感谢。我更新了我的答案。一般来说,这是一个很好的解决方案,但是哈希函数可以改进。现在,您可以有两个结构,它们的
namn
相同,但其他值不同。