如果两个数组包含相同的元素,无论这些元素出现的顺序如何,我如何在 Swift 中检查?

问题描述 投票:0回答:10

假设有两个数组...

var array1 = ["a", "b", "c"]
var array2 = ["b", "c", "a"]

我希望这两个数组的比较结果为真,下面...

var array1 = ["a", "b", "c"]
var array2 = ["b", "c", "a", "d"]

……假的。我怎样才能在 Swift 中做到这一点?我试图将两个数组都转换为集合,但由于某种原因 Set() 不断删除数组包含的一些(通常是重复的)对象。

任何帮助将不胜感激。

arrays swift swift2
10个回答
113
投票

斯威夫特 3、4

extension Array where Element: Comparable {
    func containsSameElements(as other: [Element]) -> Bool {
        return self.count == other.count && self.sorted() == other.sorted()
    }
}

// usage
let a: [Int] = [1, 2, 3, 3, 3]
let b: [Int] = [1, 3, 3, 3, 2]
let c: [Int] = [1, 2, 2, 3, 3, 3]

print(a.containsSameElements(as: b)) // true
print(a.containsSameElements(as: c)) // false


10
投票

使用集合快速比较数组

let array1 = ["a", "b", "c"]
let array2 = ["b", "c", "a", "c"]
    
let set1 = Set(array1)
let set2 = Set(array2)
    
if (set1.count == set2.count && set1 == set2) { //if you compare big sets it is recommended to compare the count of items in the sets beforehand
    //they are identical
}

Set
实现
Hashable
所以任务是实现哈希函数以与
Set

一起工作

请注意,如果重复项对您很重要,则此方法不适合

[Swift 收藏]


8
投票

你可以这样做:

  array1.sortInPlace()
  array2.sortInPlace()

  print(array1,array2)

  if array1 == array2 {
    print("equal")
  } else {
  print("not equal") 
  }

如果不想改变原来的数组我们可以做

 let sorted1 = array1.sort()
 let sorted2 = array2.sort()

  if sorted1 == sorted2 {
    print("equal")
  }else {
    print("not equal")
  }

8
投票

Swift 5.2 解决方案

var array1 = ["a", "b", "c"]
var array2 = ["b", "c", "a"]

if array1.sorted() == array2.sorted() {
    print("array 1 & array 2 are same")
}

3
投票

我知道这个问题很老了,它也不想确定array1是否是array2的子集。然而,这适用于 Swift 5.3 和 Xcode 12.3:

var array1 = ["a", "b", "c"]
var array2 = ["b", "c", "a", "d"]

print("array1 == array2? \(Set(array1) == Set(array2))")
print("array1 subset to array2? \(Set(array1).isSubset(of: Set(array2)))")

2
投票

创建比较它们的函数:

func containSameElements(var firstArray firstArray: [String], var secondArray: [String]) -> Bool {
    if firstArray.count != secondArray.count {
        return false
    } else {
        firstArray.sortInPlace()
        secondArray.sortInPlace()
        return firstArray == secondArray
    }
}

然后:

var array1 = ["a", "a", "b"]
var array2 = ["a", "b", "a"]

var array3 = ["a", "b", "c"]
var array4 = ["b", "c", "a", "d"]

print(containSameElements(firstArray: array1, secondArray: array2)) //true
print(containSameElements(firstArray: array3, secondArray: array4)) //false
print(array1) //["a", "a", "b"]
print(array2) //["a", "b", "a"]
print(array3) //["a", "b", "c"]
print(array4) //["b", "c", "a", "d"]

2
投票

这里有一个解决方案,不需要元素是

Comparable
,而只是
Equatable
。它比排序答案效率低得多,所以如果你的类型可以比较,使用其中之一。

extension Array where Element: Equatable {
    func equalContents(to other: [Element]) -> Bool {
        guard self.count == other.count else {return false}
        for e in self{
          guard self.filter{$0==e}.count == other.filter{$0==e}.count else {
            return false
          }
        }
        return true
    }
}

1
投票

Swift 4.1/Xcode 9.4 的解决方案:

extension Array where Element: Equatable {
    func containSameElements(_ array: [Element]) -> Bool {
        var selfCopy = self
        var secondArrayCopy = array
        while let currentItem = selfCopy.popLast() {
            if let indexOfCurrentItem = secondArrayCopy.index(of: currentItem) {
                secondArrayCopy.remove(at: indexOfCurrentItem)
            } else {
                return false
            }
        }
        return secondArrayCopy.isEmpty
    }
}

这个解决方案的主要优点是它比其他解决方案使用更少的内存(它总是只创建 2 个临时数组)。此外,它不需要

Element
Comparable
,只是
Equatable


1
投票

如果你的数组元素符合

Hashable
,你可以尝试使用包(它就像一个集合,注册了每个项目数量)。这里我将使用这个基于
Dictionary
的数据结构的简化版本。此扩展有助于从
Hashable
:

的数组中创建包
extension Array where Element: Hashable {
    var asBag: [Element: Int] {
        return reduce(into: [:]) {
            $0.updateValue(($0[$1] ?? 0) + 1, forKey: $1)
        }
    }
}

现在您需要从初始数组生成 2 个袋子并比较它们。我把它包装在这个扩展中:

extension Array where Element: Hashable {
    func containSameElements(_ array: [Element]) -> Bool {
        let selfAsBag = asBag
        let arrayAsBag = array.asBag
        return selfAsBag.count == arrayAsBag.count && selfAsBag.allSatisfy {
            arrayAsBag[$0.key] == $0.value
        }
    }
}

此解决方案已使用 Swift 4.2/Xcode 10 进行测试。如果您当前的 Xcode 版本低于 10.0,您可以在

Xcode9to10Preparation
中找到
allSatisfy
ArraySlice 函数。您可以使用 CocoaPods 安装此库。


-1
投票

如果我有

    array1 = ["x", "y", "z"]
    array2 = ["a", "x", "c"]

我能行

    array1.filter({array2.contains($0})

返回

["x"]

同样

    array1.filter({!array2.contains($0)})

返回

["y", "z"]

© www.soinside.com 2019 - 2024. All rights reserved.