John Difool
John Difool

Reputation: 5732

Splitting a word into pairs

I am having trouble picturing an elegant way to recreate in Swift the following code:

In Python (correct, concise, elegant):

>>> def splits(word):
...     return [(word[:i], word[i:]) for i in range(len(word) + 1)]
... 
>>> splits("abc")
[('', 'abc'), ('a', 'bc'), ('ab', 'c'), ('abc', '')]

In Swift (bogus and a bit on the heavy side):

func splits(word: String) -> [(String,String)] {
    return word.characters.indices.map {
        return (word[word.startIndex..<$0], word[$0..<word.endIndex])
    }
}

splits("abc")

"[("", "abc"), ("a", "bc"), ("ab", "c")]"

As you can see, the Swift version is missing the last pair. How can I achieve this (beside appending one last pair manually) knowing that indices on the character string don't go passed the last character in the map closure?

EDIT:

I adapted this from the answer:

func splits(word: String) -> [(String,String)] {
    let chars = word.characters
    return (0...chars.count).map {
        (String(chars.dropFirst($0)),String(chars.dropLast(chars.count - $0)))
    }
}

Upvotes: 0

Views: 124

Answers (2)

Martin R
Martin R

Reputation: 540065

Another possible solution:

func splits(word: String) -> [(String, String)] {

    return (0 ... word.characters.count).map { 
         (word.substringToIndex(word.startIndex.advancedBy($0)),
            word.substringFromIndex(word.endIndex.advancedBy(-$0)))
    }
}

splits("abc")
// [("", "abc"), ("a", "bc"), ("ab", "c"), ("abc", "")]

Upvotes: 1

user3441734
user3441734

Reputation: 17572

one possible solution

func splits(word: String) -> [(String,String)] {
    var arr:[(String,String)] = []
    (0...word.characters.count).forEach {
        arr.append(( String(word.characters.dropFirst($0)),String(word.characters.dropLast(word.characters.count - $0))))
    }
    return arr
}

let str = "abc"
let arr = splits(str)
print(arr) // [("abc", ""), ("bc", "a"), ("c", "ab"), ("", "abc")]

Upvotes: 1

Related Questions