Search code examples
arraysswiftmultidimensional-array

How to return Array<Array<String>>'s descendant's same elements?


I have an array of array of strings and I need to return descendant's same elements (not index wise, self wise).

let arrayArrayStrings: [[String]] = [
["a", "b", "e", "q"],
["a", "c", "q", "e"],
["a", "q", "d", "e"]]

And I want it to return the ["a", "e", "q"]. My brain fried while trying to do this. How can I do this efficiently?


Solution

  • Set has powerful methods to determine the relation of two sets, so a possible solution is to map the inner arrays to Set and call intersection.

    let arrayArrayStrings: [[String]] = [
    ["a", "b", "e"],
    ["a", "c", "e"],
    ["a", "d", "e"]]
    
    let arraySetStrings = arrayArrayStrings.map(Set.init)
    var commonElements = arraySetStrings[0]
    for i in 1..<arraySetStrings.count {
        commonElements.formIntersection(arraySetStrings[i])
    }
    print(commonElements.sorted())
    

    Another way to check also the position of the elements is to use the difference(from API of Array

    let arrayArrayStrings: [[String]] = [
    ["a", "b", "e"],
    ["a", "c", "e"],
    ["a", "d", "e"]]
    
    var commonElements = arrayArrayStrings[0]
    var indicesToRemove = IndexSet()
    for i in 1..<arrayArrayStrings.count {
        let diff = commonElements.difference(from: arrayArrayStrings[i])
        diff.removals.forEach { removal in
            if case .remove(offset: let offset, element: let element, associatedWith: let associatedWith) = removal {
                indicesToRemove.insert(offset)
            }
        }
    }
    commonElements.remove(atOffsets: indicesToRemove)
    print(commonElements)