How do I check in Swift if two arrays contain the same elements regardless of the order in which those elements appear in?

前端 未结 8 1158
臣服心动
臣服心动 2020-12-02 22:20

Let\'s say there are two arrays...

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

I\'d like the result of the compar

相关标签:
8条回答
  • 2020-12-02 22:35

    If elements of your arrays are conforming to Hashable you can try to use the bag (it's like a set with the registration of each item amount). Here I will use a simplified version of this data structure based on Dictionary. This extension helps to create bag from array of Hashable:

    extension Array where Element: Hashable {
        var asBag: [Element: Int] {
            return reduce(into: [:]) {
                $0.updateValue(($0[$1] ?? 0) + 1, forKey: $1)
            }
        }
    }
    

    Now you need to generate 2 bags from initial arrays and compare them. I wrapped it in this 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
            }
        }
    }
    

    This solution was tested with Swift 4.2/Xcode 10. If your current Xcode version is prior to 10.0 you can find the function allSatisfy of ArraySlice in Xcode9to10Preparation. You can install this library with CocoaPods.

    0 讨论(0)
  • 2020-12-02 22:37

    you can do something like this:

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

    and if don't want change origional array we can do

     let sorted1 = array1.sort()
     let sorted2 = array2.sort()
    
      if sorted1 == sorted2 {
        print("equal")
      }else {
        print("not equal")
      }
    
    0 讨论(0)
  • 2020-12-02 22:41

    Here is a solution that does not require the element to be Comparable, but only Equatable. It is much less efficient than the sorting answers, so if your type can be made Comparable, use one of those.

    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
        }
    }
    
    0 讨论(0)
  • 2020-12-02 22:47

    Swift 5.2 Solution

    var array1 = ["a", "b", "c"]
    var array2 = ["b", "c", "a"]
    
    if array1.sorted() == array2.sorted() {
        print("array 1 & array 2 are same")
    }
    
    0 讨论(0)
  • 2020-12-02 22:53

    Create function to compare them:

    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
        }
    }
    

    Then:

    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"]
    
    0 讨论(0)
  • 2020-12-02 22:56

    Solution for 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
        }
    }
    

    The main advantage of this solution is that it uses less memory than other (it always creates just 2 temporary arrays). Also, it does not require for Element to be Comparable, just to be Equatable.

    0 讨论(0)
提交回复
热议问题