Swift 3 写这个 if 语句的更好方式是什么?

3

我正在比较GKNoise字段中的值,然后根据噪声的级别将平铺设置到tileMap中。

此if语句通过四舍五入到最近的十分位来比较值,是否有更好的编写方式?

if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == -1.0 {
    tileMap.setTileGroup(tileGroup4, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == -0.9 {
    tileMap.setTileGroup(tileGroup4, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == -0.8 {
    tileMap.setTileGroup(tileGroup4, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == -0.7 {
    tileMap.setTileGroup(tileGroup4, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == -0.6 {
    tileMap.setTileGroup(tileGroup4, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == -0.5 {
    tileMap.setTileGroup(tileGroup3, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == -0.4 {
    tileMap.setTileGroup(tileGroup3, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == -0.3 {
    tileMap.setTileGroup(tileGroup3, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == -0.2 {
    tileMap.setTileGroup(tileGroup3, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == -0.1 {
    tileMap.setTileGroup(tileGroup3, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 0.0 {
    tileMap.setTileGroup(tileGroup2, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 0.1 {
    tileMap.setTileGroup(tileGroup2, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 0.2 {
    tileMap.setTileGroup(tileGroup2, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 0.3 {
    tileMap.setTileGroup(tileGroup2, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 0.4 {
    tileMap.setTileGroup(tileGroup2, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 0.5 {
    tileMap.setTileGroup(tileGroup1, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 0.6 {
    tileMap.setTileGroup(tileGroup1, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 0.7 {
    tileMap.setTileGroup(tileGroup1, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 0.8 {
    tileMap.setTileGroup(tileGroup1, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 0.9 {
    tileMap.setTileGroup(tileGroup1, forColumn: columns, row: rows)
}
if round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) == 1.0 {
    tileMap.setTileGroup(tileGroup1, forColumn: columns, row: rows)
}

看起来有点冗长,效率不高。


我不了解GKNoise,但你尝试使用结构体来实现了吗? - Apogee
这是一个简单的比较if语句,我想知道有没有更好的方法来做这个。 - E. Huckabee
1
当然,round(...)永远不可能等于-0.9、-0.8、... 0.9。 - Martin R
round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)) / 10) * 10) 的意思是对 (Float(columns), Float(rows)) / 10 这个位置上的 MasterNoise 值进行四舍五入,并乘以 10。 - E. Huckabee
我认为你的意思是执行 round(MasterNoise.value(atPosition: vector_float2( Float(columns),Float(rows) ) * 10)) / 10 - Knight0fDragon
显示剩余2条评论
4个回答

5

一个相对简单的改进是在条件之外计算round,使用变量存储哪个标题组的决定,并将链转换为if-then-else。这将让您使用<==>代替==:

let rounded = round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows))))
var tileGroup : SKTileGroup = nil
if rounded <= -0.6 {
    tileGroup = titleGroup4
} else if rounded <= -0.1 {
    tileGroup = titleGroup3
} else if rounded <= 0.4 {
    tileGroup = titleGroup2
} else if rounded <= 1.0 {
    tileGroup = titleGroup1
}
tileMap.setTileGroup(tileGroup, forColumn: columns, row: rows)

5
您可以使用 switchinterval matching
switch round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) {
case -1.0...(-0.6):
    tileMap.setTileGroup(tileGroup4, forColumn: columns, row: rows)
case -0.5...(-0.1):
    tileMap.setTileGroup(tileGroup3, forColumn: columns, row: rows)
case 0.0...0.4:
    tileMap.setTileGroup(tileGroup2, forColumn: columns, row: rows)
case 0.5...1.0:
    tileMap.setTileGroup(tileGroup1, forColumn: columns, row: rows)
default:
    break
}

4

我的回答超出了你的问题范围,但我个人认为这段代码能够最好地帮助你清理代码。

你可以像这样将if语句(根据你的代码外观)分组:

let noise = round(MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows))))
let tileGroup1Array = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5]
let tileGroup2Array = [0.4, 0.3, 0.2, 0.1, 0.0]
let tileGroup3Array = [-0.1, -0.2, -0.3, -0.4, -0.5]
let tileGroup4Array = [-0.6, -0.7, -0.8, -0.9, -1.0]

那么你可以检查以下内容:
if(tileGroup1Array.contains(noise)) { ... } else if(tileGroup2Array.contains(noise){ ... })

1
我并不觉得那是绝对正确的,但是嘿,随你便吧 :) 我提供我的答案是因为我认为它更适合Swift和数组方法,在浏览此解决方案时更易读,而无需弄清楚switch语句。 - jbehrens94
你可能想把 if tileGroup1Array.contains(noise) 改成 if tileGroup1Array.contains(Double(noise)),因为 if 语句需要一个 double 类型的参数。顺便说一下,我选择了你的答案,因为它是最好的和最灵活的答案。 - E. Huckabee
好主意,当我测试我的代码时,我实际上使用了let noise = 0.3而不是你帖子中的类型。 :) 谢谢把我的答案标记为你的答案! - jbehrens94
1
不用谢!感谢您能够如此迅速地提供答案。 - E. Huckabee
3
由于0.1、0.2等数字在浮点数/双精度浮点数中无法准确表示(请参考https://dev59.com/G3RB5IYBdhLWcg3wj36c),因此这种方法容易出错。更好的做法是计算`round(10 * value)`并将其与1、2等数字进行比较。 - Martin R
显示剩余9条评论

1

仅供娱乐:

根本不需要 if / switch 语句

let noise = MasterNoise.value(atPosition: vector_float2(Float(columns),Float(rows)))) + 1
let index = Int(round(noise * 10)) / 5
let tileGroup = [tileGroup4,tileGroup3,tileGroup2,tileGroup1,tileGroup1]
tileMap.setTileGroup(tileGroup[index], forColumn: columns, row: rows)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接