So
所以
split("There are fourty-eight characters in this string", 20)
should return
应该回来
["There are fourty-eig", "ht characters in thi","s string"]
If I make currentIndex = string.startIndex and then try to advance() it further than a string.endIndex, I get "fatal error: can not increment endIndex" before I check if my currentIndex < string.endIndex so the code below doesn't work
如果我使currentIndex = string.startIndex,然后尝试进一步提前()它比string.endIndex,我得到“致命错误:不能增加endIndex”我检查我的currentIndex
var string = "12345"
var currentIndex = string.startIndex
currentIndex = advance(currentIndex, 6)
if currentIndex > string.endIndex {currentIndex = string.endIndex}
6 个解决方案
#1
13
I just answered a similar question on SO and thought I can provide a more concise solution:
我刚刚在SO上回答了类似的问题,并认为我可以提供更简洁的解决方案:
Swift 2
func split(str: String, _ count: Int) -> [String] {
return 0.stride(to: str.characters.count, by: count).map { i -> String in
let startIndex = str.startIndex.advancedBy(i)
let endIndex = startIndex.advancedBy(count, limit: str.endIndex)
return str[startIndex..<endIndex]
}
}
Swift 3
func split(_ str: String, _ count: Int) -> [String] {
return stride(from: 0, to: str.characters.count, by: count).map { i -> String in
let startIndex = str.index(str.startIndex, offsetBy: i)
let endIndex = str.index(startIndex, offsetBy: count, limitedBy: str.endIndex) ?? str.endIndex
return str[startIndex..<endIndex]
}
}
Swift 4
Changed to a while
loop for better efficiency and made into a String's extension by popular request:
更改为while循环以提高效率,并按流行请求制作String的扩展名:
extension String {
func split(by length: Int) -> [String] {
var startIndex = self.startIndex
var results = [Substring]()
while startIndex < self.endIndex {
let endIndex = self.index(startIndex, offsetBy: length, limitedBy: self.endIndex) ?? self.endIndex
results.append(self[startIndex..<endIndex])
startIndex = endIndex
}
return results.map { String($0) }
}
}
#2
10
This problem could be easily solved with just one pass through the characters sequence:
只需一次通过字符序列即可轻松解决此问题:
Swift 2.2
extension String {
func splitByLength(length: Int) -> [String] {
var result = [String]()
var collectedCharacters = [Character]()
collectedCharacters.reserveCapacity(length)
var count = 0
for character in self.characters {
collectedCharacters.append(character)
count += 1
if (count == length) {
// Reached the desired length
count = 0
result.append(String(collectedCharacters))
collectedCharacters.removeAll(keepCapacity: true)
}
}
// Append the remainder
if !collectedCharacters.isEmpty {
result.append(String(collectedCharacters))
}
return result
}
}
let foo = "There are fourty-eight characters in this string"
foo.splitByLength(20)
Swift 3.0
extension String {
func splitByLength(_ length: Int) -> [String] {
var result = [String]()
var collectedCharacters = [Character]()
collectedCharacters.reserveCapacity(length)
var count = 0
for character in self.characters {
collectedCharacters.append(character)
count += 1
if (count == length) {
// Reached the desired length
count = 0
result.append(String(collectedCharacters))
collectedCharacters.removeAll(keepingCapacity: true)
}
}
// Append the remainder
if !collectedCharacters.isEmpty {
result.append(String(collectedCharacters))
}
return result
}
}
let foo = "There are fourty-eight characters in this string"
foo.splitByLength(20)
Since String is a pretty complicated type, ranges and indexes could have different computational costs depending on the view. These details are still evolving, thus the above one-pass solution might be a safer choice.
由于String是一种非常复杂的类型,因此根据视图,范围和索引可能具有不同的计算成本。这些细节仍在不断发展,因此上述一次性解决方案可能是一个更安全的选择。
Hope this helps
希望这可以帮助
#3
3
You must not use range that exceeds the string size. The following method will demonstrates how to do it:
您不能使用超出字符串大小的范围。以下方法将演示如何执行此操作:
extension String {
func split(len: Int) -> [String] {
var currentIndex = 0
var array = [String]()
let length = self.characters.count
while currentIndex < length {
let startIndex = self.startIndex.advancedBy(currentIndex)
let endIndex = startIndex.advancedBy(len, limit: self.endIndex)
let substr = self.substringWithRange(Range(start: startIndex, end: endIndex))
array.append(substr)
currentIndex += len
}
return array
}
}
Usage:
用法:
"There are fourty-eight characters in this string".split(20)
//output: ["There are fourty-eig", "ht characters in thi", "s string"]
or
要么
"????????????????????????????⛵".split(3)
//output: ["????????????", "????????????", "????⛵"]
Edit: Updated the answer to work with Xcode 7 beta 6. The advance
method is gone, replaced by advancedBy
instance methods of Index
. The advancedBy:limit:
version is especially useful in this case.
编辑:更新了使用Xcode 7 beta 6的答案。高级方法消失了,取而代之的是Index的advancedBy实例方法。在这种情况下,advancedBy:limit:version特别有用。
#4
3
String extension based on "Code Different" answer:
基于“Code Different”答案的字符串扩展:
Swift 4, Swift 3
Swift 4,Swift 3
extension String {
func components(withLength length: Int) -> [String] {
return stride(from: 0, to: self.characters.count, by: length).map {
let start = self.index(self.startIndex, offsetBy: $0)
let end = self.index(start, offsetBy: length, limitedBy: self.endIndex) ?? self.endIndex
return self[start..<end]
}
}
}
Usage
用法
let str = "There are fourty-eight characters in this string"
let components = str.components(withLength: 20)
#5
2
endIndex
is not a valid index; it is one more than the valid range.
endIndex不是有效索引;它比有效范围多一个。
#6
0
Here is a string extension you can use if you want to split a String at a certain length, but also take into account words:
如果要将String拆分为一定长度,可以使用以下字符串扩展,还要考虑以下单词:
Swift 4:
斯威夫特4:
func splitByLength(_ length: Int, seperator: String) -> [String] {
var result = [String]()
var collectedWords = [String]()
collectedWords.reserveCapacity(length)
var count = 0
let words = self.components(separatedBy: " ")
for word in words {
count += word.count + 1 //add 1 to include space
if (count > length) {
// Reached the desired length
result.append(collectedWords.map { String($0) }.joined(separator: seperator) )
collectedWords.removeAll(keepingCapacity: true)
count = word.count
collectedWords.append(word)
} else {
collectedWords.append(word)
}
}
// Append the remainder
if !collectedWords.isEmpty {
result.append(collectedWords.map { String($0) }.joined(separator: seperator))
}
return result
}
This is a modification of Matteo Piombo's answer above.
这是Matteo Piombo上面回答的修改。
Usage
用法
let message = "Here is a string that I want to split."
let message_lines = message.splitByLength(18, separator: " ")
//output: [ "Here is a string", "that I want to", "split." ]
#1
13
I just answered a similar question on SO and thought I can provide a more concise solution:
我刚刚在SO上回答了类似的问题,并认为我可以提供更简洁的解决方案:
Swift 2
func split(str: String, _ count: Int) -> [String] {
return 0.stride(to: str.characters.count, by: count).map { i -> String in
let startIndex = str.startIndex.advancedBy(i)
let endIndex = startIndex.advancedBy(count, limit: str.endIndex)
return str[startIndex..<endIndex]
}
}
Swift 3
func split(_ str: String, _ count: Int) -> [String] {
return stride(from: 0, to: str.characters.count, by: count).map { i -> String in
let startIndex = str.index(str.startIndex, offsetBy: i)
let endIndex = str.index(startIndex, offsetBy: count, limitedBy: str.endIndex) ?? str.endIndex
return str[startIndex..<endIndex]
}
}
Swift 4
Changed to a while
loop for better efficiency and made into a String's extension by popular request:
更改为while循环以提高效率,并按流行请求制作String的扩展名:
extension String {
func split(by length: Int) -> [String] {
var startIndex = self.startIndex
var results = [Substring]()
while startIndex < self.endIndex {
let endIndex = self.index(startIndex, offsetBy: length, limitedBy: self.endIndex) ?? self.endIndex
results.append(self[startIndex..<endIndex])
startIndex = endIndex
}
return results.map { String($0) }
}
}
#2
10
This problem could be easily solved with just one pass through the characters sequence:
只需一次通过字符序列即可轻松解决此问题:
Swift 2.2
extension String {
func splitByLength(length: Int) -> [String] {
var result = [String]()
var collectedCharacters = [Character]()
collectedCharacters.reserveCapacity(length)
var count = 0
for character in self.characters {
collectedCharacters.append(character)
count += 1
if (count == length) {
// Reached the desired length
count = 0
result.append(String(collectedCharacters))
collectedCharacters.removeAll(keepCapacity: true)
}
}
// Append the remainder
if !collectedCharacters.isEmpty {
result.append(String(collectedCharacters))
}
return result
}
}
let foo = "There are fourty-eight characters in this string"
foo.splitByLength(20)
Swift 3.0
extension String {
func splitByLength(_ length: Int) -> [String] {
var result = [String]()
var collectedCharacters = [Character]()
collectedCharacters.reserveCapacity(length)
var count = 0
for character in self.characters {
collectedCharacters.append(character)
count += 1
if (count == length) {
// Reached the desired length
count = 0
result.append(String(collectedCharacters))
collectedCharacters.removeAll(keepingCapacity: true)
}
}
// Append the remainder
if !collectedCharacters.isEmpty {
result.append(String(collectedCharacters))
}
return result
}
}
let foo = "There are fourty-eight characters in this string"
foo.splitByLength(20)
Since String is a pretty complicated type, ranges and indexes could have different computational costs depending on the view. These details are still evolving, thus the above one-pass solution might be a safer choice.
由于String是一种非常复杂的类型,因此根据视图,范围和索引可能具有不同的计算成本。这些细节仍在不断发展,因此上述一次性解决方案可能是一个更安全的选择。
Hope this helps
希望这可以帮助
#3
3
You must not use range that exceeds the string size. The following method will demonstrates how to do it:
您不能使用超出字符串大小的范围。以下方法将演示如何执行此操作:
extension String {
func split(len: Int) -> [String] {
var currentIndex = 0
var array = [String]()
let length = self.characters.count
while currentIndex < length {
let startIndex = self.startIndex.advancedBy(currentIndex)
let endIndex = startIndex.advancedBy(len, limit: self.endIndex)
let substr = self.substringWithRange(Range(start: startIndex, end: endIndex))
array.append(substr)
currentIndex += len
}
return array
}
}
Usage:
用法:
"There are fourty-eight characters in this string".split(20)
//output: ["There are fourty-eig", "ht characters in thi", "s string"]
or
要么
"????????????????????????????⛵".split(3)
//output: ["????????????", "????????????", "????⛵"]
Edit: Updated the answer to work with Xcode 7 beta 6. The advance
method is gone, replaced by advancedBy
instance methods of Index
. The advancedBy:limit:
version is especially useful in this case.
编辑:更新了使用Xcode 7 beta 6的答案。高级方法消失了,取而代之的是Index的advancedBy实例方法。在这种情况下,advancedBy:limit:version特别有用。
#4
3
String extension based on "Code Different" answer:
基于“Code Different”答案的字符串扩展:
Swift 4, Swift 3
Swift 4,Swift 3
extension String {
func components(withLength length: Int) -> [String] {
return stride(from: 0, to: self.characters.count, by: length).map {
let start = self.index(self.startIndex, offsetBy: $0)
let end = self.index(start, offsetBy: length, limitedBy: self.endIndex) ?? self.endIndex
return self[start..<end]
}
}
}
Usage
用法
let str = "There are fourty-eight characters in this string"
let components = str.components(withLength: 20)
#5
2
endIndex
is not a valid index; it is one more than the valid range.
endIndex不是有效索引;它比有效范围多一个。
#6
0
Here is a string extension you can use if you want to split a String at a certain length, but also take into account words:
如果要将String拆分为一定长度,可以使用以下字符串扩展,还要考虑以下单词:
Swift 4:
斯威夫特4:
func splitByLength(_ length: Int, seperator: String) -> [String] {
var result = [String]()
var collectedWords = [String]()
collectedWords.reserveCapacity(length)
var count = 0
let words = self.components(separatedBy: " ")
for word in words {
count += word.count + 1 //add 1 to include space
if (count > length) {
// Reached the desired length
result.append(collectedWords.map { String($0) }.joined(separator: seperator) )
collectedWords.removeAll(keepingCapacity: true)
count = word.count
collectedWords.append(word)
} else {
collectedWords.append(word)
}
}
// Append the remainder
if !collectedWords.isEmpty {
result.append(collectedWords.map { String($0) }.joined(separator: seperator))
}
return result
}
This is a modification of Matteo Piombo's answer above.
这是Matteo Piombo上面回答的修改。
Usage
用法
let message = "Here is a string that I want to split."
let message_lines = message.splitByLength(18, separator: " ")
//output: [ "Here is a string", "that I want to", "split." ]