将 Swift 字符串切成 2 个字母的字符串的最佳方法是什么? [英] What's the best way to cut Swift string into 2-letter-strings?
问题描述
我需要将一个字符串分成 2 个字母的部分.比如friend"->fr"ie"nd".(好吧,这是我将HEX字符串更改为Uint8数组的一个步骤)
I need to split a string into 2-letter pieces. Like "friend" -> "fr" "ie" "nd". (Okay, its a step for me to change HEX string to Uint8 Array)
我的代码是
for i=0; i<chars.count/2; i++ {
let str = input[input.startIndex.advancedBy(i*2)..<input.startIndex.advancedBy(i*2+1)]
bytes.append(UInt8(str,radix: 16)!)
}
但我不知道为什么我不能使用 Range 来做这个拆分.而且我不知道当 i*2+1 大于字符串的长度时会发生什么.那么将 Swift 字符串切成 2 个字母的字符串的最佳方法是什么?
But I don't know why I cannot use Range to do this split. And I have no idea what will happen when i*2+1 is bigger than string's length. So what's the best way to cut Swift string into 2-letter-strings?
推荐答案
您的范围不起作用,因为您需要使用 ...
而不是 ..<
.
Your range wasn't working because you need to use ...
instead of ..<
.
let input = "ff103"
var bytes = [UInt8]()
let strlen = input.characters.count
for i in 0 ..< (strlen + 1)/2 {
let str = input[input.startIndex.advancedBy(i*2)...input.startIndex.advancedBy(min(strlen - 1, i*2+1))]
bytes.append(UInt8(str,radix: 16) ?? 0)
}
print(bytes) // [255, 16, 3]
<小时>
这是将字符串拆分为 2 个字母的字符串的另一种方法.advancedBy()
是一个开销很大的 O(n) 操作,所以这个版本会跟踪 start
并把它提前 2
每次循环,而 end
基于 start
:
Here is another take on splitting the string into 2-letter strings. advancedBy()
is an expensive O(n) operation, so this version keeps track of start
and just marches it ahead by 2
each loop, and end
is based on start
:
let input = "friends"
var strings = [String]()
let strlen = input.characters.count
var start = input.startIndex
let lastIndex = strlen > 0 ? input.endIndex.predecessor() : input.startIndex
for i in 0 ..< (strlen + 1)/2 {
start = i > 0 ? start.advancedBy(2) : start
let end = start < lastIndex ? start.successor() : start
let str = input[start...end]
strings.append(str)
}
print(strings) // ["fr", "ie", "nd", "s"]
<小时>
替代答案:
使用范围可能有点矫枉过正.只需将字符添加到数组并从中生成 String
就很容易:
Using ranges is probably overkill. It is easy just to add the characters to an array and make String
s from those:
let input = "friends"
var strings = [String]()
var newchars = [Character]()
for c in input.characters {
newchars.append(c)
if newchars.count == 2 {
strings.append(String(newchars))
newchars = []
}
}
if newchars.count > 0 {
strings.append(String(newchars))
}
print(strings) // ["fr", "ie", "nd", "s"]
<小时>
这是制作[UInt8]
的新版本:
let input = "ff103"
var bytes = [UInt8]()
var newchars = [Character]()
for c in input.characters {
newchars.append(c)
if newchars.count == 2 {
bytes.append(UInt8(String(newchars), radix: 16) ?? 0)
newchars = []
}
}
if newchars.count > 0 {
bytes.append(UInt8(String(newchars), radix: 16) ?? 0)
}
print(bytes) // [255, 16, 3]
<小时>
基于@LeoDabus 的回答,我们可以使用一个返回任意长度子字符串的方法和一个返回[UInt8]
的计算属性进行扩展:
extension String {
func substringsOfLength(length: Int) -> [String] {
if length < 1 { return [] }
var result:[String] = []
let chars = Array(characters)
for index in 0.stride(to: chars.count, by: length) {
result.append(String(chars[index ..< min(index+length, chars.count)]))
}
return result
}
var toUInt8: [UInt8] {
var result:[UInt8] = []
let chars = Array(characters)
for index in 0.stride(to: chars.count, by: 2) {
let str = String(chars[index ..< min(index+2, chars.count)])
result.append(UInt8(str, radix: 16) ?? 0)
}
return result
}
}
let input = "friends"
let str2 = input.substringsOfLength(2) // ["fr", "ie", "nd", "s"]
let str0 = input.substringsOfLength(0) // []
let str3 = input.substringsOfLength(3) // ["fri", "end", "s"]
let bytes = "ff107".toUInt8 // [255, 16, 7]
这篇关于将 Swift 字符串切成 2 个字母的字符串的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!