查找两个 Swift 数组是否包含相同的元素
Find whether two Swift Arrays contain the same elements
我有两个数组
let a1 = [obj1, obj2, obj3]
let a2 = [obj3, obj2, obj1]
假设数组元素是不可排序的自定义对象。我只想检查 Array
是否以任何顺序包含相同的元素。
我试过这个:
if a1==a2 { print("S1 is the same as S2") }
else { print("S1 is not the same as S2") }
但我得到 "S1 is not the same as S2" 作为输出。
我能想到的只有两个解决方案
- 排序和比较(如果元素不可排序,比如复数,则不起作用)
- 从一个数组中减去另一个数组
是否有内置函数或操作来检查它们是否相等,而不考虑顺序?
我发现 只有 sortable Array
s.
的答案
如果数组有重复,这 2 个解决方案也有效。
场景 1:元素可排序
let a1 = [1, 2, 3]
let a2 = [3, 2, 1]
let equals = a1.sorted() == a2.sorted()
时间复杂度:我们需要对两个数组进行排序,所以时间复杂度为O(n * log n) + O( m * log m)
Space 复杂性:创建了两个数组的临时副本,因此所需的 space 是 O(n) + O (m).
其中n
是a1
中的元素个数,m
是a2
中的元素个数。
场景 2:元素不可排序
func equals<Element:Equatable>(listA:[Element], listB:[Element]) -> Bool {
guard listA.count == listB.count else { return false }
var listB = listB
for a in listA {
if let indexB = listB.indexOf(a) {
listB.removeAtIndex(indexB)
} else {
return false
}
}
return listB.isEmpty
}
时间复杂度:我们正在迭代第一个数组,每次我们对第二个数组执行线性搜索所以O(n * m)
Space 复杂性:我们创建了第二个数组的副本,因此 O(m)
如果项目是唯一且相等的(如您的示例),请转换为集合并比较集合:
let a1 = [1, 2, 3]
let a2 = [3, 2, 1]
Set(a1) == Set(a2)
通过一些 futzing,这可以用于任意 class:
class Person : NSObject {
let name: String
init(name:String) {self.name = name}
override func isEqual(other: AnyObject?) -> Bool {
return other is Person && (other as! Person).name == self.name
}
override var hashValue : Int {
return self.name.hashValue
}
}
let a1 = [Person(name:"Matt"), Person(name:"Sam")]
let a2 = [Person(name:"Sam"), Person(name:"Matt")]
Set(a1) == Set(a2)
您可以将它们转换为按定义未排序的 Set
或 NSSet
实例并进行比较。更好的是,不要使用数组,而是首先考虑使用集合。
let a1 = [1, 4, 5]
let a2 = [4, 5, 1]
let s1 = NSSet(array: a1)
let s2 = NSSet(array: a2)
print(s1 == s2) // Prints "true"
如果对象可能在您的数组中出现多次,您需要使用 NSCountedSet
来代替,它还会计算每个对象在集合中出现的频率:
let a1 = [1, 1, 2]
let a2 = [1, 2, 2]
let s1 = NSSet(array: a1)
let s2 = NSSet(array: a2)
print(s1 == s2) // Prints "true"
let c1 = NSCountedSet(array: a1)
let c2 = NSCountedSet(array: a2)
print(c1 == c2) // Prints "false"
我有两个数组
let a1 = [obj1, obj2, obj3]
let a2 = [obj3, obj2, obj1]
假设数组元素是不可排序的自定义对象。我只想检查 Array
是否以任何顺序包含相同的元素。
我试过这个:
if a1==a2 { print("S1 is the same as S2") }
else { print("S1 is not the same as S2") }
但我得到 "S1 is not the same as S2" 作为输出。
我能想到的只有两个解决方案
- 排序和比较(如果元素不可排序,比如复数,则不起作用)
- 从一个数组中减去另一个数组
是否有内置函数或操作来检查它们是否相等,而不考虑顺序?
我发现 Array
s.
如果数组有重复,这 2 个解决方案也有效。
场景 1:元素可排序
let a1 = [1, 2, 3]
let a2 = [3, 2, 1]
let equals = a1.sorted() == a2.sorted()
时间复杂度:我们需要对两个数组进行排序,所以时间复杂度为O(n * log n) + O( m * log m)
Space 复杂性:创建了两个数组的临时副本,因此所需的 space 是 O(n) + O (m).
其中n
是a1
中的元素个数,m
是a2
中的元素个数。
场景 2:元素不可排序
func equals<Element:Equatable>(listA:[Element], listB:[Element]) -> Bool {
guard listA.count == listB.count else { return false }
var listB = listB
for a in listA {
if let indexB = listB.indexOf(a) {
listB.removeAtIndex(indexB)
} else {
return false
}
}
return listB.isEmpty
}
时间复杂度:我们正在迭代第一个数组,每次我们对第二个数组执行线性搜索所以O(n * m)
Space 复杂性:我们创建了第二个数组的副本,因此 O(m)
如果项目是唯一且相等的(如您的示例),请转换为集合并比较集合:
let a1 = [1, 2, 3]
let a2 = [3, 2, 1]
Set(a1) == Set(a2)
通过一些 futzing,这可以用于任意 class:
class Person : NSObject {
let name: String
init(name:String) {self.name = name}
override func isEqual(other: AnyObject?) -> Bool {
return other is Person && (other as! Person).name == self.name
}
override var hashValue : Int {
return self.name.hashValue
}
}
let a1 = [Person(name:"Matt"), Person(name:"Sam")]
let a2 = [Person(name:"Sam"), Person(name:"Matt")]
Set(a1) == Set(a2)
您可以将它们转换为按定义未排序的 Set
或 NSSet
实例并进行比较。更好的是,不要使用数组,而是首先考虑使用集合。
let a1 = [1, 4, 5]
let a2 = [4, 5, 1]
let s1 = NSSet(array: a1)
let s2 = NSSet(array: a2)
print(s1 == s2) // Prints "true"
如果对象可能在您的数组中出现多次,您需要使用 NSCountedSet
来代替,它还会计算每个对象在集合中出现的频率:
let a1 = [1, 1, 2]
let a2 = [1, 2, 2]
let s1 = NSSet(array: a1)
let s2 = NSSet(array: a2)
print(s1 == s2) // Prints "true"
let c1 = NSCountedSet(array: a1)
let c2 = NSCountedSet(array: a2)
print(c1 == c2) // Prints "false"