Disons qu'il y a deux tableaux ...
var array1 = ["a", "b", "c"]
var array2 = ["b", "c", "a"]
J'aimerais que le résultat de la comparaison de ces deux tableaux soit vrai, et le suivant ...
var array1 = ["a", "b", "c"]
var array2 = ["b", "c", "a", "d"]
... être faux. Comment puis-je atteindre cet objectif dans Swift? J'ai essayé de convertir les deux tableaux en ensembles, mais pour une raison quelconque, Set () continue de supprimer certains objets (généralement dupliqués) contenus dans le tableau.
Toute aide serait appréciée.
Swift 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
vous pouvez faire quelque chose comme ça:
array1.sortInPlace()
array2.sortInPlace()
print(array1,array2)
if array1 == array2 {
print("equal")
} else {
print("not equal")
}
et si vous ne voulez pas changer le tableau d'origine que nous pouvons faire
let sorted1 = array1.sort()
let sorted2 = array2.sort()
if sorted1 == sorted2 {
print("equal")
}else {
print("not equal")
}
Créer une fonction pour les comparer:
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
}
}
Ensuite:
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"]
Voici une solution qui n'exige pas que l'élément soit Comparable
, mais seulement Equatable
. Il est beaucoup moins efficace que les réponses de tri. Si votre type peut être comparé, utilisez l’une de celles-ci.
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
}
}
Solution pour 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
}
}
Le principal avantage de cette solution est qu’elle utilise moins de mémoire que les autres (elle ne crée toujours que 2 tableaux temporaires). En outre, il n'est pas nécessaire que Element
soit Comparable
, mais simplement Equatable
.
Si des éléments de vos tableaux sont conformes à Hashable
, vous pouvez essayer d’utiliser le sac (c’est comme un ensemble avec l’enregistrement de la quantité de chaque article). Ici, je vais utiliser une version simplifiée de cette structure de données basée sur Dictionary
. Cette extension permet de créer un sac à partir du tableau de Hashable
:
extension Array where Element: Hashable {
var asBag: [Element: Int] {
return reduce(into: [:]) {
$0.updateValue(($0[$1] ?? 0) + 1, forKey: $1)
}
}
}
Maintenant, vous devez générer 2 sacs à partir de tableaux initiaux et les comparer. Je l'ai enveloppé dans cette extension:
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
}
}
}
Cette solution a été testée avec Swift 4.2/Xcode 10. Si votre version actuelle de Xcode est antérieure à 10.0, vous pouvez trouver la fonction allSatisfy
de ArraySlice
dans Xcode9to10Preparation . Vous pouvez installer cette bibliothèque avec CocoaPods.