Swift - sorting characters in each string in an ar

2019-05-01 20:53发布

问题:

So this question is a follow up to this one: swift string permutations allowing the same strings

There, I asked about all possible mutations that I can make with a defined set of strings. What I am trying to do next is to filter out all results that have the same combination, but in a different order.

So if the input is: ["AB", "AC", "CA", "CB"], the output should be ["AB", "AC", "CB"], since "AC" and "CA" have the same building blocks.

So my thought was to first sort each string alphabetically, and maybe then create a Set.

I am already stuck on the first part :(

let array = ["AB", "AC", "DC", "CA", "CB"]
print(type(of: array))
print(array)

let sortedArray = array.map{ $0.sorted() }
print(type(of: sortedArray))
print(sortedArray)

The output is:

Array<String>
["AB", "AC", "DC", "CA", "CB"]
Array<Array<Character>>
[["A", "B"], ["A", "C"], ["C", "D"], ["A", "C"], ["B", "C"]]

While I expected for the sortedArray:

["AB", "AC", "CD", "AC", "BC"]

Then I thought to join the individual strings back together:

print(array.map{ $0.joined() } )

Resulting in ambiguous reference to member 'joined()'

But how to fix this I don't understand.

I also saw this one: swift sort characters in a string where the following code is used:

var nonSortedString = "5121"
var sortedString = String(Array(nonSortedString.characters).sort())

But I don't see how to apply that using map and friends (after converting to Swift 4)

Any help appreciated.

回答1:

If you want to take a string, sort its characters, and build a new string from that, in Swift 4 you can:

let string = "foobar"

let sortedString = String(string.sorted())

That results in:

"abfoor"

So, going back to your original problem, you can take you strings, which are a collection of permutations, and build a sorted array of combinations like so:

let permutations = ["AB", "AC", "DC", "CA", "CB"]

// build set of combinations where each string has, itself, been sorted alphabetically

let combinations = Set(permutations.map { String($0.sorted()) })

// convert set (which removed duplicates) back to an array and sort it

let result = Array(combinations).sorted()

That results in:

["AB", "AC", "BC", "CD"]



回答2:

A different approach... This solution uses another reduce function implementation from the Sequence protocol

let reduced = array.map({ String($0.sorted()) }).reduce(into: [String]() ){ (result, element)  -> Void in
    if !result.contains(element)
    {
        result.append(element)
    }
}.sorted()

print(reduced)

The result is...

["AB", "AC", "BC", "CD"]