如果数组在最后,如何遍历数组并重新启动?

时间:2016-10-29 19:27:31

标签: ios arrays swift

我有一系列颜色,我想在iOS中应用于uitableviewcells

let colorPalet = [
            UIColor(red: 255.0/255.0, green: 159.0/255.0, blue: 112.0/255.0, alpha: 1),
            UIColor(red: 81.0/255.0, green: 218.0/255.0, blue: 168.0/255.0, alpha: 1),
            UIColor(red: 2.0/255.0, green: 207.0/255.0, blue: 255.0/255.0, alpha: 1),
            UIColor(red: 144.0/255.0, green: 153.0/255.0, blue: 166.0/255.0, alpha: 1)
        ]
        cell.backgroundColor = colorPalet[indexPath.row]

问题是,当indexPath.row大于colorPalet数组时,它会崩溃,因为数组中没有更多条目。如果它在Swift中的数组末尾,如何再次通过数组启动iteratie?

5 个答案:

答案 0 :(得分:5)

你可以使用modulo:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<form id="frm-contact">
  Full name:
  <input type="text" name="contact-name">
  <br>Email Address:
  <input type="text" name="contact-email">
  <br>Mobile No:
  <input type="tel" name="contact-tel">

  <button type="submit" id="btn-submit" class="btn">Submit</button>

</form>

答案 1 :(得分:0)

for index in 0..array.count {

    //Do stuff here
    if (index == array.count -1)
    {
        index = 0
    }
}

答案 2 :(得分:0)

您可以使用以下内容:

let index = indexPath.row%4
cell.something = colorPalet[index]

答案 3 :(得分:0)

accepted answer已经涵盖了OP的特定情况(表格视图中的单元格颜色),而这个答案将接近更一般的问题标题:

  

如果数组在最后,如何遍历数组并重新开始?

模数操作自然会浮现在脑海中,

truncatedIndex = runningIndexDividend % divisor 

但是如果我们要在长期运行的应用程序中使用它,那么runningIndexDividend不必要地增加到比divisor大得多的值(可能在理论上的设计情况下,甚至导致整数溢出...)?对于这种情况,另一种主要是利用Swift的Sequence整洁性的替代方案是使用一个即时生成序列:一个根据需要懒惰地构造其下一个元素的序列。

使用全局sequence(state:next:)函数

对于构造重复遍历给定数组的(无限)序列(用尾部“连接”头部)的情况,您可以使用the global sequence(state:next:) function

例如,应用于您的示例(此处将colorPalet存储为ColorSettings实用程序类的静态成员,如果在线程应用程序中使用静态属性,则只知道可能的非线程安全性):

class ColorSettings {
    private static let colorPalet = [
        UIColor(red: 255.0/255.0, green: 159.0/255.0, blue: 112.0/255.0, alpha: 1),
        UIColor(red: 81.0/255.0, green: 218.0/255.0, blue: 168.0/255.0, alpha: 1),
        UIColor(red: 2.0/255.0, green: 207.0/255.0, blue: 255.0/255.0, alpha: 1),
        UIColor(red: 144.0/255.0, green: 153.0/255.0, blue: 166.0/255.0, alpha: 1)
    ]

    static let colorSequence = sequence(
        state: 1,
        next: { (idx: inout Int) -> UIColor? in
            guard colorPalet.count > 0 else { return nil }
            defer { idx == colorPalet.count ? (idx = 1) : (idx += 1) }
            /* alternatively (loose clarity/semantics to gain brevity)
            defer { idx = idx % colorPalet.count + 1 } */
            return colorPalet[idx-1]
    })
}

示例“用法”(并非真正用于此应用程序)

// example usage
let numberOfRowsInSection = 7
for (row, color) in zip(0..<numberOfRowsInSection,
                        ColorSettings.colorSequence) {
    // ...
    print(row, color)
} /* 0 UIExtendedSRGBColorSpace 1 0.623529 0.439216 1
     1 UIExtendedSRGBColorSpace 0.317647 0.854902 0.658824 1
     2 UIExtendedSRGBColorSpace 0.00784314 0.811765 1 1
     3 UIExtendedSRGBColorSpace 0.564706 0.6 0.65098 1
     4 UIExtendedSRGBColorSpace 1 0.623529 0.439216 1
     5 UIExtendedSRGBColorSpace 0.317647 0.854902 0.658824 1
     6 UIExtendedSRGBColorSpace 0.00784314 0.811765 1 1        */

请注意,状态不会在两个单独的colorSequence遍历之间保存。即,如果复制上面的循环并应用于其他地方,则第一个状态将始终对应于第一个颜色。

还要注意,当构造如上所述的无限生成序列时,序列自然不能自行终止(除了空nil数组的情况外,没有colorPalet返回。因此,它的实际应用主要是与上面使用zip的有限序列结合使用。

使用带有AnyIterator

的外部状态属性

如果您宁愿将结束状态保留在一个遍历中作为后续遍历的起点(不重置它,如上所述),您可以使用类似于上面的方法,但使用帮助{{1 }}属性与state结合使用:

AnyIterator

使用示例:

class ColorSettings {
    private static let colorPalet = [
        UIColor(red: 255.0/255.0, green: 159.0/255.0, blue: 112.0/255.0, alpha: 1),
        UIColor(red: 81.0/255.0, green: 218.0/255.0, blue: 168.0/255.0, alpha: 1),
        UIColor(red: 2.0/255.0, green: 207.0/255.0, blue: 255.0/255.0, alpha: 1),
        UIColor(red: 144.0/255.0, green: 153.0/255.0, blue: 166.0/255.0, alpha: 1)
    ]

    private static var idx: Int = 1
    static let colorIterator: AnyIterator<UIColor> = AnyIterator {
        guard colorPalet.count > 0 else { return nil }
        defer { idx == colorPalet.count ? (idx = 1) : (idx += 1) }
        return colorPalet[idx-1]
    }
}

答案 4 :(得分:0)

使colorPalet成为实例变量。您可以将下面的代码移到课程顶部:

let colorPalet = [
            UIColor(red: 255.0/255.0, green: 159.0/255.0, blue: 112.0/255.0, alpha: 1),
            UIColor(red: 81.0/255.0, green: 218.0/255.0, blue: 168.0/255.0, alpha: 1),
            UIColor(red: 2.0/255.0, green: 207.0/255.0, blue: 255.0/255.0, alpha: 1),
            UIColor(red: 144.0/255.0, green: 153.0/255.0, blue: 166.0/255.0, alpha: 1)
        ]

这样您就不会为您配置的每个单元格创建颜色数组。然后在ROC的答案中使用模数('%)代码:

cell.backgroudColor = colorPalet[indexPath.row % colorPalet.count]