在Swift中进行代码查询有哪些技巧?它对安全性的关注似乎使打高尔夫球变得困难,但这几乎没有技巧,甚至更有用。Swift中是否有任何功能可以帮助它在某些应用程序的代码高尔夫中脱颖而出?
请为每个答案发布一个提示。
在Swift中进行代码查询有哪些技巧?它对安全性的关注似乎使打高尔夫球变得困难,但这几乎没有技巧,甚至更有用。Swift中是否有任何功能可以帮助它在某些应用程序的代码高尔夫中脱颖而出?
请为每个答案发布一个提示。
Answers:
真正有用的一件事是使用...
或创建范围..<
运算符
例如
array[0..<n] //first n elements of array
array[k..<n] //kth through nth elements of array
array[k...n] //kth through n-1 elements of array
因此,要获得数组的第二至第四值
let myArray = ["ab", "cd", "ef", "gh", "ij", "kl", "mn", "op"]
print(myArray[1..<4]) //["cd", "ef", "gh"]
let a = [3, 1, 4, 1, 5, 9]
使用
for v in a[0...3]{print(v)}
比8个字节短
for n in 0...3{let v=a[n];print(v)}
for n in 0...3{print(a[n])}
无效吗?
使用保持函数的变量与使用函数本身的变量可以帮助:
65个字节:
var r:(String,Int)->String={return String(repeating:$0,count:$1)}
66个字节:
func r(s:String,i:Int)->String{return String(repeating:s,count:i)}
此处的差异不大,但在某些困惑中会显示更多。
看前面的例子让我想起了什么。有时,如果您将足够多次使用某个函数,则值得为其重命名:
这个:
String(repeating:$0,count:$1)
对此:
var r:(String,Int)->String={return String(repeating:$0,count:$1)}
或者,实际上,这样更好:
var r=String.init(repeating:count:)
这样你就打电话 r("Hello World",8)
代替String(repeating:"Hello World",count:8)
我曾经创建一个闭包而不设置参数类型,因此创建了一个简短的答案:
var f={(i)->Int in i-1+i%2*2}
编译器推断i
在Int
。
如果需要的数组Ints
,请使用Range
创建它:
Array(0...5)
这与以下操作相同:
[0,1,2,3,4,5]
If
or Switch
:而不是这样做:
if n==0{return "a"}else if n==1{return "b"}else{return "c"}
您可能可以这样做:
return ["a","b","c"][n]
如果您经常使用类型转换,则可能要创建一个类型别名:
typealias f=Float
请记住,您通常不需要return
在map
函数中使用关键字。
try
在Swift 2.x及更高版本中,传统上通过将指针作为NSError
对象传递给对象来处理错误的函数称为函数参数throw
。
这意味着:
var regex = NSRegularExpression(pattern: "\"((http)s?://.*?)\"", options: nil, error: nil)
现在看起来像:
do {
let regex = try NSRegularExpression(pattern: "\"((http)s?://.*?)\"", options: [])
} catch {
print(error)
}
可以使用try?
或缩短此时间try!
。 try?
将计算表达式nil
是否抛出错误。 try!
如果抛出错误,将使程序崩溃,并且仅应在永远不会抛出错误的情况下使用。
let regex = try! NSRegularExpression(pattern: "\"((http)s?://.*?)\"", options: [])
try?
并try!
从do-try-catch
循环中至少保存13个字节。请注意,您还可以通过[]
为选项传入一个空数组()来节省至少一个字节nil
。
for-in loops
通过数组进行迭代以获取单个值,例如内部元素的总和,或者元素的乘积可能实际上太简单了。您可以只使用该reduce()
方法。一些例子:
var array = [1,2,3,4,5,6,7]
用for-in
循环将数组中的元素相加:
var sum = 0
for item in array{
sum += item
}
print(sum)
可以简化为:
print(array.reduce(0, +))
并使用for-in循环获取数组内部元素的乘积:
var multiplier = 1
for item in array{
multiplier *= item
}
print(multiplier)
也可以简化为:
print(array.reduce(1, *))
**
通过pow
手动调用相比,声明函数会丢失更多字节吗?
有时,您可以通过退回到Foundation类型来节省字节,而不是使用纯Swift类型。比较访问NSString
vs Swift String
类型的子字符串:
let x:NSString = "hello world"
x.substringToIndex(5) // "hello"
let y = "hello world"
y.substringToIndex(y.startIndex.advancedBy(5)) // "hello"
即使通过声明x
为丢失了9个字符NSString
,使用Foundation类型也可以节省25个字符,因为对于Swift 类型,substringToIndex
将Int
用作参数NSString
,而将用作Index
struct(String.CharacterView.Index
)String
。
我应该注意,基金会类型的可用性在多个平台(OS X,Linux等)上可能有所不同。大多数Foundation类都NSUnimplemented
在Swift的开源版本中。
.map()
与尾随的闭包语法结合可以收紧for循环。我们可以将要迭代的内容放入数组中,然后.map()
对每个元素执行一些操作。
例如,我们可以用.map()
一行写那个老栗子Fizzbuzz。
var d: [Int] = Array(1...100)
d.map{$0%15 == 0 ? print("Fizzbuzz") : $0%3 == 0 ? print("Fizz") : $0%5 == 0 ? print("Buzz") : print($0)}
在高尔夫以外,.map()
可以帮助减少重复。例如,假设您有一个需要以编程方式定位的视图。您可以将视图的锚点放入一个匿名数组中,并对其进行.map()
遍历以将每个约束条件设置.isActive
为true,如下所示:
_ = [
view.topAnchor.constraint(equalTo: view.topAnchor, constant: 40),
view.widthAnchor.constraint(equalTo: view.widthAnchor),
view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
].map { $0.isActive = true }
forEach
在第二个示例中使用它更好吗? map
应该真正用于转换数组的内容,而不是用作迭代快捷方式。在这种情况下,您将丢弃结果。
考虑您要使用while
循环,并且要在条件和要遵循的块中使用相同的内容。然后,在元组中进行内联分配很可能会有所帮助。属性越长,效果越好!考虑一下(短3个字节):
func f(s:[Int]){var k=s,i=0;while(i=k.count,i>0).1{print(i,i+k[i-1]);k.removeLast();}}
在此:
func g(s:[Int]){var k=s,i=0;while k.count>0{i=k.count;print(i,i+k[i-1]);k.removeLast();}}
注意这一(i=k.count,i>0).1
部分,这很有趣。
受到Herman Lauenstein的 答案之一的启发。
不幸的是,Swift不支持*
Python的String乘法。您可以改用的一种好方法是String(repeating:count:)
,但是不幸的是,这并不是真正的高尔夫运动。比较这两种方法:
var a=String(repeating:"abc",count:3)
和
var a="";for _ in 0..<3{a+="abc"}
第二个是短几个字节,但是不能在闭包中使用……更好的是,它也可以在闭包中使用:
(0..<3).map{_ in"abc"}.joined()
如果我多次这样做会怎样?好了,您可以使用String.init()
。现在,这可以节省很多字节。例如(68个字节):
let k=String.init(repeating:count:)
print(k("abcd",9)+k("XYZxyz",9))
而不是(74个字节):
print(String(repeating:"abcd",count:9)+String(repeating:"XYZxyz",count:9))
或(70个字节):
var f={String(repeating:$0,count:$1)}
print(f("abcd",9)+f("XYZxyz",9))
但是请确保您的字符串足够长。如果您使用的String(repeating:"abc",3)
,它是很多更好地使用"abcabcabc"
来代替。