Reputation: 5732
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
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
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