我怎样才能交错两个数组?
How can I interleave two arrays?
如果我有两个数组,例如
let one = [1,3,5]
let two = [2,4,6]
我想要 merge/interleave 以下模式中的数组 [one[0]、two[0]、one[1]、two[1] 等....]
//prints [1,2,3,4,5,6]
let comibned = mergeFunction(one, two)
print(combined)
什么是实现组合功能的好方法?
func mergeFunction(one: [T], _ two: [T]) -> [T] {
var mergedArray = [T]()
//What goes here
return mergedArray
}
如果你只是想交错两个数组,你可以这样做:
let maxIndex = max(one.count, two.count)
var mergedArray = Array<T>()
for index in 0..<maxIndex {
if index < one.count { mergedArray.append(one[index]) }
if index < two.count { mergedArray.append(two[index]) }
}
return mergedArray
如果两个数组的长度相同,那么这是一个可能的解决方案:
let one = [1,3,5]
let two = [2,4,6]
let merged = zip(one, two).flatMap { [[=10=], ] }
print(merged) // [1, 2, 3, 4, 5, 6]
这里zip()
并行枚举数组,returns一个序列
一对(2 元素元组),每个数组中有一个元素。 flatMap()
从每对创建一个 2 元素数组并将结果连接起来。
如果数组可以有不同的长度,那么你追加
结果的较长数组的额外元素:
func mergeFunction<T>(one: [T], _ two: [T]) -> [T] {
let commonLength = min(one.count, two.count)
return zip(one, two).flatMap { [[=11=], ] }
+ one.suffixFrom(commonLength)
+ two.suffixFrom(commonLength)
}
Swift3 的更新:
func mergeFunction<T>(_ one: [T], _ two: [T]) -> [T] {
let commonLength = min(one.count, two.count)
return zip(one, two).flatMap { [[=12=], ] }
+ one.suffix(from: commonLength)
+ two.suffix(from: commonLength)
}
使用Swift5,您可以使用以下Playground示例代码之一来解决您的问题。
#1。使用 zip(_:_:)
function and Collection
's flatMap(_:)
方法
let one = [1, 3, 5, 7]
let two = [2, 4, 6]
let array = zip(one, two).flatMap({ [[=10=], ] })
print(array) // print: [1, 2, 3, 4, 5, 6]
苹果states:
If the two sequences passed to zip(_:_:)
are different lengths, the resulting sequence is the same length as the shorter sequence.
#2。使用符合 Sequence
and IteratorProtocol
协议
的对象
struct InterleavedSequence<T>: Sequence, IteratorProtocol {
private let firstArray: [T]
private let secondArray: [T]
private let thresholdIndex: Int
private var index = 0
private var toggle = false
init(firstArray: [T], secondArray: [T]) {
self.firstArray = firstArray
self.secondArray = secondArray
self.thresholdIndex = Swift.min(firstArray.endIndex, secondArray.endIndex)
}
mutating func next() -> T? {
guard index < thresholdIndex else { return nil }
defer {
if toggle {
index += 1
}
toggle.toggle()
}
return !toggle ? firstArray[index] : secondArray[index]
}
}
let one = [1, 3, 5, 7]
let two = [2, 4, 6]
let sequence = InterleavedSequence(firstArray: one, secondArray: two)
let array = Array(sequence)
print(array) // print: [1, 2, 3, 4, 5, 6]
/// Alternates between the elements of two sequences.
/// - Parameter keepSuffix:
/// When `true`, and the sequences have different lengths,
/// the suffix of `interleaved` will be the suffix of the longer sequence.
func interleaved<Sequence: Swift.Sequence>(
with sequence: Sequence,
keepingLongerSuffix keepSuffix: Bool = false
) -> AnySequence<Element>
where Sequence.Element == Element {
keepSuffix
? .init { () -> AnyIterator<Element> in
var iterators = (
AnyIterator( self.makeIterator() ),
AnyIterator( sequence.makeIterator() )
)
return .init {
defer { iterators = (iterators.1, iterators.0) }
return iterators.0.next() ?? iterators.1.next()
}
}
: .init(
zip(self, sequence).lazy.flatMap { [[=10=], ] }
)
}
let oddsTo7 = stride(from: 1, to: 7, by: 2)
let evensThrough10 = stride(from: 2, through: 10, by: 2)
let oneThrough6 = Array(1...6)
XCTAssertEqual(
Array( oddsTo7.interleaved(with: evensThrough10) ),
oneThrough6
)
XCTAssertEqual(
Array(
oddsTo7.interleaved(with: evensThrough10, keepingLongerSuffix: true)
),
oneThrough6 + [8, 10]
)
如果我有两个数组,例如
let one = [1,3,5]
let two = [2,4,6]
我想要 merge/interleave 以下模式中的数组 [one[0]、two[0]、one[1]、two[1] 等....]
//prints [1,2,3,4,5,6]
let comibned = mergeFunction(one, two)
print(combined)
什么是实现组合功能的好方法?
func mergeFunction(one: [T], _ two: [T]) -> [T] {
var mergedArray = [T]()
//What goes here
return mergedArray
}
如果你只是想交错两个数组,你可以这样做:
let maxIndex = max(one.count, two.count)
var mergedArray = Array<T>()
for index in 0..<maxIndex {
if index < one.count { mergedArray.append(one[index]) }
if index < two.count { mergedArray.append(two[index]) }
}
return mergedArray
如果两个数组的长度相同,那么这是一个可能的解决方案:
let one = [1,3,5]
let two = [2,4,6]
let merged = zip(one, two).flatMap { [[=10=], ] }
print(merged) // [1, 2, 3, 4, 5, 6]
这里zip()
并行枚举数组,returns一个序列
一对(2 元素元组),每个数组中有一个元素。 flatMap()
从每对创建一个 2 元素数组并将结果连接起来。
如果数组可以有不同的长度,那么你追加 结果的较长数组的额外元素:
func mergeFunction<T>(one: [T], _ two: [T]) -> [T] {
let commonLength = min(one.count, two.count)
return zip(one, two).flatMap { [[=11=], ] }
+ one.suffixFrom(commonLength)
+ two.suffixFrom(commonLength)
}
Swift3 的更新:
func mergeFunction<T>(_ one: [T], _ two: [T]) -> [T] {
let commonLength = min(one.count, two.count)
return zip(one, two).flatMap { [[=12=], ] }
+ one.suffix(from: commonLength)
+ two.suffix(from: commonLength)
}
使用Swift5,您可以使用以下Playground示例代码之一来解决您的问题。
#1。使用 zip(_:_:)
function and Collection
's flatMap(_:)
方法
let one = [1, 3, 5, 7]
let two = [2, 4, 6]
let array = zip(one, two).flatMap({ [[=10=], ] })
print(array) // print: [1, 2, 3, 4, 5, 6]
苹果states:
If the two sequences passed to
zip(_:_:)
are different lengths, the resulting sequence is the same length as the shorter sequence.
#2。使用符合 Sequence
and IteratorProtocol
协议
的对象
struct InterleavedSequence<T>: Sequence, IteratorProtocol {
private let firstArray: [T]
private let secondArray: [T]
private let thresholdIndex: Int
private var index = 0
private var toggle = false
init(firstArray: [T], secondArray: [T]) {
self.firstArray = firstArray
self.secondArray = secondArray
self.thresholdIndex = Swift.min(firstArray.endIndex, secondArray.endIndex)
}
mutating func next() -> T? {
guard index < thresholdIndex else { return nil }
defer {
if toggle {
index += 1
}
toggle.toggle()
}
return !toggle ? firstArray[index] : secondArray[index]
}
}
let one = [1, 3, 5, 7]
let two = [2, 4, 6]
let sequence = InterleavedSequence(firstArray: one, secondArray: two)
let array = Array(sequence)
print(array) // print: [1, 2, 3, 4, 5, 6]
/// Alternates between the elements of two sequences.
/// - Parameter keepSuffix:
/// When `true`, and the sequences have different lengths,
/// the suffix of `interleaved` will be the suffix of the longer sequence.
func interleaved<Sequence: Swift.Sequence>(
with sequence: Sequence,
keepingLongerSuffix keepSuffix: Bool = false
) -> AnySequence<Element>
where Sequence.Element == Element {
keepSuffix
? .init { () -> AnyIterator<Element> in
var iterators = (
AnyIterator( self.makeIterator() ),
AnyIterator( sequence.makeIterator() )
)
return .init {
defer { iterators = (iterators.1, iterators.0) }
return iterators.0.next() ?? iterators.1.next()
}
}
: .init(
zip(self, sequence).lazy.flatMap { [[=10=], ] }
)
}
let oddsTo7 = stride(from: 1, to: 7, by: 2)
let evensThrough10 = stride(from: 2, through: 10, by: 2)
let oneThrough6 = Array(1...6)
XCTAssertEqual(
Array( oddsTo7.interleaved(with: evensThrough10) ),
oneThrough6
)
XCTAssertEqual(
Array(
oddsTo7.interleaved(with: evensThrough10, keepingLongerSuffix: true)
),
oneThrough6 + [8, 10]
)