【问题标题】:Iterate over array treating index 0 differently迭代数组以不同方式处理索引 0
【发布时间】:2015-05-09 03:27:09
【问题描述】:

我发现了很多关于迭代数组的问题和答案,但没有找到一个解释如何迭代数组内容、识别和处理索引 0 的不同方法。

这样做的原因是我有一个传入的数据流,我想将它们显示为它们随时间变化的值的图。一个简单的方法是创建一个CGMutablePathRef,计算x 和y 坐标,然后CGPathAddLineToPoint 继续画线。当然路径必须从某处开始,因此对于第一个索引,我需要将 y 坐标设置为 0 偏移量,计算 x 坐标并使用 CGPathMoveToPoint 设置路径的开头。

我所做的是处理索引 0,然后复制数组并丢弃索引 0,并处理复制数组中的剩余项(除了 0 之外的所有项)。我也可以只设置一个布尔值 false,如果循环中的 false 将该点作为索引 0 处理,则将布尔值设置为 true。这两种方法都有些混乱。

我真正不喜欢的部分是每次生成路径时都复制值数组。有没有一种简单的方法可以遍历从索引 1 开始的数组?

我缺少一些方便的数组语法吗?

    var yOffset = 0.0
    temperaturePath = CGPathCreateMutable()
    CGPathMoveToPoint(temperaturePath, nil, xOffsetForTemperature(temperatures[0]), yOffset)
    var remainingTemperatures = temperatures
    remainingTemperatures.removeAtIndex(0)

    for value in remainingTemperatures {

        yOffset += verticalAdvanceAmount
        let temperatureXOffset = xOffsetForTemperature(value)
        CGPathAddLineToPoint(temperaturePath, nil, temperatureXOffset, yOffset)
    }

【问题讨论】:

    标签: swift core-graphics


    【解决方案1】:

    使用切片。

    temperaturePath = CGPathCreateMutable()
    CGPathMoveToPoint(temperaturePath, nil, xOffsetForTemperature(temperatures[0]), yOffset)
    
    yOffset = 0.0
    for value in temperatures.dropFirst() {
        yOffset += verticalAdvanceAmount
        let temperatureXOffset = xOffsetForTemperature(value)
        CGPathAddLineToPoint(temperaturePath, nil, temperatureXOffset, yOffset)
    }
    

    Swift Standard Library Referencethis article by Nate Cook 中的更多详细信息。

    您可以选择将数据存储为CGPoint 的数组,在这种情况下,您只需使用CGContextAddLines 进行初始移动并在一次调用中添加所有线段。

    您可能会发现,一旦您拥有大量数据点,一遍又一遍地描边整个路径是低效的,在这种情况下,您可能会发现 this Q&A 很有帮助。

    【讨论】:

    • for value in dropFirst(temperatures)
    • 链接的答案与我打算做的事情一致,但我意识到我现在只需要非常简单。每次数组太大而无法在屏幕上绘制时,我都会从数组的开头丢弃一些点 - 所以滚动很好但没有历史记录。我希望我可以在这里标记多个正确的答案。
    【解决方案2】:

    如果目标是将数组永久拆分为第一个元素和其他所有元素,请使用removeAtIndex,因为它返回已删除的内容:

    var temperatures = // ...
    let first = temperatures.removeAtIndex(0) // alters temperatures
    

    如果目标是在不改变原始数组的情况下导出第一个元素和其他所有元素,则可以进行切片:

    let first = temperatures.first!
    let rest = temperatures[1..<temperatures.count]
    

    但这是有捷径的特殊情况;使用dropFirst,保持原始数组不变:

    let first = temperatures.first!
    let rest = dropFirst(temperatures)
    

    (请注意,我派生临时变量firstrest 只是为了清楚。在现实生活中,您可以跳过它们。temperatures[1..&lt;temperatures.count]dropFirst(temperatures) 都可以直接用for...in 枚举。)

    【讨论】:

    • 我不确定这是否能解决问题 - 温度会累积新值,因此我无法在每次抽签时破坏它。在以这种方式处理之前,我仍然需要制作数组的副本,不是吗?
    • 我不知道你刚才说了什么。我没有建议你“摧毁”任何东西!你要求更简洁的语法,我提供了一些。
    • 我的意思是我不能丢弃温度数组中的任何值,因为它们应该在每个 drawRect 中绘制:-我希望有一些范围修饰符来“用于温度值”,它可以处理除索引 0
    • 看看我书中的这一部分:apeth.com/swiftBook/…
    • 我是个白痴。你应该使用dropFirst。我已经修改了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 2017-10-15
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    相关资源
    最近更新 更多