Home > database >  Swift: How to merge several sets of String?
Swift: How to merge several sets of String?

Time:09-15

Hello I have this case:

enum Test {
    static let all: [Test] = [.a, .b, .c]
   
    case a, b, c

    var chars: Set<String> {
        switch self {
            case .a: 
                return ["a", "b", "c"]
            case .b: 
                return ["d", "e", "f"]
            case .c: 
                return ["g", "h", "i"]
        }
    }
}

I would like to create a set that maps all the chars from all the cases, so the result would be:

["a", "b", "c", "d", "e", "f", "g", "h", "i"]

I tried this:

static var allCharacters: Set<String> {
    return Test.all
        .joined()
        .flatMap { $0.chars }
}

But this doesn't work. What should I do?

Thank you for your help

CodePudding user response:

I would do:

let allStrings = Test.all.reduce(into: Set()) { acc, newSet in 
    acc.formUnion(newSet.chars) 
}

reduce starts with Set() as the acc, and for each newSet in Test.all, does acc.formUnion(newSet.chars). As a whole, this computes the union of all the sets in Test.all.map(\.chars).

Notes:

  • Test can conform to CaseIterable. Then you don't need to declare all. An allCases property will be automatically generated for you.
  • There is no joined method on an array of Tests. joined is available on sequences of sequences, and returns a FlattenSequence, which is not what you want.

CodePudding user response:

You can try

 static var allCharacters: Set<String> {
     return Set(Test.all.flatMap { $0.chars })
 }

OR

 static var allCharacters: Set<String> {
     let res =  Test.all.map { $0.chars }
     return res.reduce(into: Set()) { partialResult, arr in
         partialResult = partialResult.union(arr)
     }
 }
  • Related