背景:Swift3(beta)
简短概述:愚蠢的解决方案
var myChars:[Character] = ["C", "a", "t", "!", ""]
let separators = repeatElement(Character("-"), count: myChars.count)
let zipped = zip(myChars, separators).lazy.flatMap { [$0, $1] }
let joined = String(zipped.dropLast())
阐述
好的。这让我疯狂了。部分原因是因为我陷入了“join”语义的困境中。join方法非常有用,但当你远离它非常特定(但常见)的字符串连接案例时,它正在同时执行两件事情。它将其他元素拼接到原始序列中,然后将2个深度字符数组(字符串数组)展平为一个单一数组(字符串)。
OP在数组中使用单个字符使我的大脑走神了。上面给出的答案是获得所需结果的最简单方法。将单个字符转换为单个字符字符串,然后使用join方法。
如果您想单独考虑这两个部分...我们从原始输入开始:
var input:[Character] = ["C", "a", "t", "!", ""]
在我们可以使用分隔符拼接字符之前,我们需要一个分隔符集合。在这种情况下,我们希望有一个伪集合,它是一遍又一遍地重复相同的内容,而无需实际制作具有那么多元素的数组:
let separators = repeatElement(Character(","), count: myChars.count)
这将返回一个Repeated
对象(有趣的是,您无法使用常规的init
方法实例化它)。
现在我们想要用分隔符拼接/编织原始输入:
let zipped = zip(myChars, separators).lazy.flatMap { [$0, $1] }
zip
函数返回一个Zip2Sequence
(需要通过自由函数实例化,而不是直接对象引用)。当枚举Zip2Sequence时,它只枚举(eachSequence1, eachSequence2)
的成对元组。 flatMap
表达式将其转换为两个序列中交替元素的单个系列。
对于大型输入,这将创建一个相当大的中间序列,很快就会被丢弃。因此,我们在其中插入了lazy
访问器,它允许仅在访问元素时按需计算变换(考虑迭代器)。
最后,我们知道可以从任何类型的字符序列创建字符串。因此,我们直接将其传递给字符串创建。我们添加了dropLast()
以避免添加最后一个逗号。
let joined = String(zipped.dropLast())
将其以这种方式分解的有价值之处(代码行数肯定更多,因此必须有一个补救价值),是我们可以深入了解许多工具,以解决类似但不完全相同于join
的问题。例如,假设我们想要尾随逗号?Joined不是答案。假设我们想要非常量分隔符?只需重新设计第二行即可。等等...
joinWithSeparator(Character(","))
。 - Travis GriggsjoinWithSeparator
只支持字符串类型。 - JALjoined(separator:)
替换了joinWithSeparator
。 - Travis Griggs