Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Swift中一次迭代两个集合_Swift - Fatal编程技术网

在Swift中一次迭代两个集合

在Swift中一次迭代两个集合,swift,Swift,假设我有一个数组[1,2,3,4,5]。如何一次迭代两次 Iteration 1: (1, 2) Iteration 2: (3, 4) Iteration 3: (5, nil) 如果数组的元素数为偶数,则可以编写如下内容: for i in 0..<arr.count/2 { print(arr[2*i...2*i+1]) } 更新以上两种解决方案都可以通过使用map而不是手动循环来简化: let pairs = (0..<arr.count/2).map { (ar

假设我有一个数组
[1,2,3,4,5]
。如何一次迭代两次

Iteration 1: (1, 2)
Iteration 2: (3, 4)
Iteration 3: (5, nil)

如果数组的元素数为偶数,则可以编写如下内容:

for i in 0..<arr.count/2 {
    print(arr[2*i...2*i+1])
}
更新以上两种解决方案都可以通过使用
map
而不是手动循环来简化:

let pairs = (0..<arr.count/2).map { (arr[$0*2], arr[$0*2+1]) }
print(pairs) // prints [(1, 2), (3, 4)]
您可以扩展
集合
,使此
功能可用于所有集合:

extension Collection {
    func pairs() -> [(Element, Element?)] {
        guard !isEmpty else { return [] }
        return (0..<count/2+count%2).map {
            let i1 = index(startIndex, offsetBy: $0*2)
            let i2 = index(after: i1)
            return (self[i1], i2 < endIndex ? self[i2] : nil)
        }
    }
}
扩展集合{
func pairs()->[(元素,元素?]{
守卫!我没有其他{return[]}

return(0..一种方法是将数组封装在一个类中。获取项目对的返回值是可选的,以防止超出范围的调用

例如:

class Pairs {

    let source = [1, 2, 3, 4, 5]  // Or set with init()
    var offset = 0

    func nextpair() -> (Int?, Int?) {
        var first: Int? = nil
        var second: Int? = nil
        if offset < source.count {
            first = source[offset]
            offset++
        }
        if offset < source.count {
            second = source[offset]
            offset++
        }
        return (first, second)
    }

}
let seq = (1...).prefix(5)
for pair in seq.pairs() { print(pair) }
类对{
让source=[1,2,3,4,5]//或用init()设置
var偏移量=0
func nextpair()->(Int?,Int?){
第一个变量:Int?=nil
第二个变量:Int?=nil
如果偏移量
我个人不喜欢在一半的列表中循环(主要是因为划分),所以我喜欢这样做:

let array = [1,2,3,4,5];
var i = 0;

while i < array.count {
    var a = array[i];
    var b : Int? = nil;
    if i + 1 < array.count {
        b = array[i+1];
    }
    print("(\(a), \(b))");

    i += 2;
}
let数组=[1,2,3,4,5];
var i=0;
而我
通过递增2循环数组


如果希望元素中有nil,则需要使用可选项。

您可以使用称为stride(to:,by:)的渐进循环,每n个元素迭代一次元素:

let array = Array(1...5)

let pairs = stride(from: 0, to: array.endIndex, by: 2).map {
    (array[$0], $0 < array.index(before: array.endIndex) ? array[$0.advanced(by: 1)] : nil)
}   // [(.0 1, {some 2}), (.0 3, {some 4}), (.0 5, nil)]

print(pairs)  // "[(1, Optional(2)), (3, Optional(4)), (5, nil)]\n"

这将适用于任何类型的收藏:

let string = "12345"
for substring in string.unfoldSubSequences(limitedTo: 2) {
    print(substring)  // "12" "34" "5"
}
您可以使用
sequence()
和迭代器的
next()
方法进行迭代 在成对的连续元素上。这适用于任意序列, 不仅是阵列:

let a = "ABCDE"

for pair in sequence(state: a.makeIterator(), next: { it in
    it.next().map { ($0, it.next()) }
}) {
    print(pair)
}
输出:

("A", Optional("B")) ("C", Optional("D")) ("E", nil) 例如:

class Pairs {

    let source = [1, 2, 3, 4, 5]  // Or set with init()
    var offset = 0

    func nextpair() -> (Int?, Int?) {
        var first: Int? = nil
        var second: Int? = nil
        if offset < source.count {
            first = source[offset]
            offset++
        }
        if offset < source.count {
            second = source[offset]
            offset++
        }
        return (first, second)
    }

}
let seq = (1...).prefix(5)
for pair in seq.pairs() { print(pair) }
请注意,这些对是惰性生成的,没有中间数组 如果您想要一个包含所有对的数组,那么

let pairs = Array([1, 2, 3, 4, 5].pairs())
print(pairs) // [(1, Optional(2)), (3, Optional(4)), (5, nil)]

做这项工作。

这与所问的问题不同,但我使用了序列扩展,它生成一个数组,将原始序列按任意所需大小分块:

extension Sequence {
    func clump(by clumpsize:Int) -> [[Element]] {
        let slices : [[Element]] = self.reduce(into:[]) {
            memo, cur in
            if memo.count == 0 {
                return memo.append([cur])
            }
            if memo.last!.count < clumpsize {
                memo.append(memo.removeLast() + [cur])
            } else {
                memo.append([cur])
            }
        }
        return slices
    }
}
扩展序列{
func clump(按clumpsize:Int)->[[Element]]{
让切片:[[Element]]=self.reduce(变成:[]){
备忘录,请进来
如果memo.count==0{
返回备忘录。附加([cur])
}
如果memo.last!.count

所以
[1,2,3,4,5].clump(by:2)
产生
[[1,2],[3,4],[5]
,现在,如果您愿意,您可以迭代它。

扩展以拆分数组

extension Array {
   func chunked(into size: Int) -> [[Element]] {
      return stride(from: 0, to: count, by: size).map {
      Array(self[$0 ..< Swift.min($0 + size, count)]) }
   }
}

let result = [1...10].chunked(into: 2)
扩展数组{
func分块(分为大小:Int)->[[Element]]{
返回步幅(从:0到:计数,按:大小)。映射{
数组(self[$0..
这是我的解决方案,其中包括一个
reduce
和几个
guard
s

extension Array {
  var touplesOfTwo: [(Element,Element?)] {
    self.reduce(into: [(Element,Element?)]()) {
      guard let last = $0.last else { $0.append( ($1,nil) ); return }
      let lastIndex = $0.count - 1
      guard let _ = last.1 else { $0[lastIndex].1 = $1; return }
      $0.append( ($1,nil) )
    }
  }
}
let list = [1,4,3,7,2,9,6,5]
let queues = list.map { $0 }
let touplesList = queues.touplesOfTwo
print("\(touplesList)")
// [(1, Optional(4)), (3, Optional(7)), (2, Optional(9)), (6, Optional(5))]

您应该将a声明为let,因为它的值不会更改。注意:考虑到输入数组只有整数(Int),因此它永远不会为零,所以元组的第一个元素不需要是可选的,因此您可以将其声明为[(Int,Int?]酷!对于不能用整数索引的东西怎么样?@fumoboy007我不知道你可以有一个不能用整数nvm索引的数组。任何值得一次迭代两次的东西都会有一个
可移动的
@PaulBrewczynski的索引。如果处理基因与否没有任何区别。只是个人偏好erence(语法)。如果这让你感到不安,就把它改为+1。当然,真正的目标是实现ruby的
每个片段
,我们不限于成对,而是可以将一个序列分为任意给定长度的子序列(三元组等)。@matt:类似于?我发布了这个答案,因为这里的请求是填充“不完整”用nil而不是截断块,但是是的,它非常相似。太好了,我希望你会有这样的东西!非常干净!一个问题:你不需要在
it.next().map{}
中使用可选链接吗,因为
it.next()
返回一个可选的?@fumoboy007不,这就是为什么不简单地
让i2=index(在:i1之后)是的,那会更简单,@LeoDabus
let queues=list.map{$0}
是无意义的sbtw Swift是一种类型推断语言
reduce(to:[])
并且不需要使用两个保护语句。
guard let last=$0.last,last.1==nil else{
<0.append($1,nil))
正是我需要的!谢谢。
extension Sequence {
    func clump(by clumpsize:Int) -> [[Element]] {
        let slices : [[Element]] = self.reduce(into:[]) {
            memo, cur in
            if memo.count == 0 {
                return memo.append([cur])
            }
            if memo.last!.count < clumpsize {
                memo.append(memo.removeLast() + [cur])
            } else {
                memo.append([cur])
            }
        }
        return slices
    }
}
extension Array {
   func chunked(into size: Int) -> [[Element]] {
      return stride(from: 0, to: count, by: size).map {
      Array(self[$0 ..< Swift.min($0 + size, count)]) }
   }
}

let result = [1...10].chunked(into: 2)
extension Array {
  var touplesOfTwo: [(Element,Element?)] {
    self.reduce(into: [(Element,Element?)]()) {
      guard let last = $0.last else { $0.append( ($1,nil) ); return }
      let lastIndex = $0.count - 1
      guard let _ = last.1 else { $0[lastIndex].1 = $1; return }
      $0.append( ($1,nil) )
    }
  }
}
let list = [1,4,3,7,2,9,6,5]
let queues = list.map { $0 }
let touplesList = queues.touplesOfTwo
print("\(touplesList)")
// [(1, Optional(4)), (3, Optional(7)), (2, Optional(9)), (6, Optional(5))]