swift - 如何用多个跨步的空格分隔字符串中的字符?
问题描述
我有一个工作函数,可以用空格分隔每个 n 字符,效果很好。
这是代码(Swift 5):
extension String {
/// Creates a new string, separating characters specified by stride lenght.
/// - Parameters:
/// - stride: Desired stride lenght.
/// - separator: Character to be placed in between separations
func separate(every stride: Int, with separator: Character) -> String {
return String(self.enumerated().map { $0 > 0 && $0 % stride == 0 ? [separator, $1] : [$1] }.joined())
}
}
这会像这样打印一个示例字符串 1234123412341234
1234 1234 1234 1234
现在,我如何将这个字符串 1234123412341234 与多个步长分开,例如在第 4 个字符之后设置空白,然后在第 6 个字符之后,然后在第 5 个字符之后,如下所示:
1234 123412 34123 4
解决方案
这是我将如何做到这一点:
// Prints sequences of bools using 1/0s for easy reading
func p<S: Sequence>(_ bools: S) where S.Element == Bool {
print(bools.map { $0 ? "1" : "0"}.joined())
}
// E.g. makeWindow(span: 3) returns 0001
func makeWindow(span: Int) -> UnfoldSequence<Bool, Int> {
return sequence(state: span) { state in
state -= 1
switch state {
case -1: return nil
case 0: return true
case _: return false
}
}
}
// E.g. calculateSpacePositions(spans: [4, 6, 5]) returns 000100000100001
func calculateSpacePositions<S: Sequence>(spans: S)
-> LazySequence<FlattenSequence<LazyMapSequence<S, UnfoldSequence<Bool, Int>>>>
where S.Element == Int {
return spans.lazy.flatMap(makeWindow(span:))
}
extension String {
func insertingSpaces(at spans: [Int]) -> String {
let spacePositions = calculateSpacePositions(spans: spans + [Int.max])
// p(spacePositions.prefix(self.count))
let characters = zip(inputString, spacePositions)
.flatMap { character, shouldHaveSpace -> [Character] in
return shouldHaveSpace ? [character, "_"] : [character]
}
return String(characters)
}
}
let inputString = "1234123412341234"
let result = inputString.insertingSpaces(at: [4, 6, 5])
print(result)
主要思想是我想要zip(self, spacePositions)
,以便获得 的字符序列self
,以及一个布尔值,告诉我是否应该在当前字符之后附加一个空格。
为了计算spacePositions
,我首先创建了一个函数,当给定Int
输入时span
,它会返回span
false
s 后跟 a true
。例如makeWindow(span: 3)
返回一个产生的序列false, false, false, true
。
从那里开始,只需为输入的每个元素创建一个窗口,然后使用flatMap
. 我懒惰地做这一切,所以我们实际上不需要存储所有这些重复的布尔值。
不过我碰到了一个障碍。如果你给出输入[4, 6, 5]
,我会习惯的输出是4
字符、空格、6
字符、空格、5
字符、结束。字符串的其余部分丢失了,因为zip
产生了一个长度等于两个输入中较短的长度的序列。
为了解决这个问题,我追加Int.max
了spans
输入。这样,空间位置为000010000001000001 ...now followed by Int.max falses
。
推荐阅读
- parsing - 如果我想构建一个抽象语法树,关于规则右侧的项目数量的最佳实践是什么?
- python - 无法从 'lasagne.utils' 导入名称 'int_types' (c:\python38\lib\site-packages\lasagne\utils.py)
- javascript - 我不知道 forEach() 在哪里工作
- python - 最小示例 Python 模块导入的问题
- database - 如何在单个 OIM 环境中为多个 Oracle 数据库使用单个数据库用户管理 (DBUM-12.2.1.3.0) 连接器
- python - 根据特定列中的值在 pandas 数据框中创建列
- python - 在 pyspark 中对流数据进行分组
- python - 用于 PDF 到 Excel 的 Python 和 PDFPlumber
- xamarin - 具有绑定问题的 Xamarin 表单 FlyoutPage
- javascript - 如何在 React boostrap 中使用单选按钮