Swift에서 코드 골프에 대한 팁은 무엇입니까? 안전에 중점을두면 골프를 타기가 어려워 지지만 팁이 적고 유용합니다. Swift에는 특정 응용 프로그램에서 코드 골프에 탁월한 기능이 있습니까?
답변 당 하나의 팁을 게시하십시오.
Swift에서 코드 골프에 대한 팁은 무엇입니까? 안전에 중점을두면 골프를 타기가 어려워 지지만 팁이 적고 유용합니다. Swift에는 특정 응용 프로그램에서 코드 골프에 탁월한 기능이 있습니까?
답변 당 하나의 팁을 게시하십시오.
답변:
정말 유용한 한 가지는 ...
or ..<
연산자를 사용하여 범위를 만드는 것입니다.
예를 들어
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
따라서 배열의 2-4 번째 값을 얻으려면
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
a Range
를 사용 하여 배열 을 만듭니다.
Array(0...5)
이것은 다음과 같은 일을합니다.
[0,1,2,3,4,5]
If
또는 대신 배열 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!
로부터 적어도 13 바이트 저장 do-try-catch
루프를. []
옵션 대신 빈 배열 ( )을 전달하여 하나 이상의 바이트를 절약 할 수도 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
않습니까?
스위프트의 삼항 연산자는 매우 간결하다 : condition ? action : other
행동
조건이 맞으면 한 가지를 수행하고 그렇지 않은 경우 다른 것을 수행하십시오.
textColor = bgIsBlack ? .white : .black
이것은 만드는 textColor
배경이 다른 색상의 경우 배경이 검은 색 또는 검은 색이면 흰색을.
무 연합 연산자는 더욱 간결합니다. a ?? b
JSON의 특정 키를 검사하여 키 값을 제목 텍스트로 표시 할 수 있다고 가정 해 보겠습니다. 키가 없으면 (예 : 값이 nil) 제목에 기본 텍스트를 지정하려고합니다.
title = keysValue ?? "Not Available"
당신은 체인 수 forEach
에서 enumerated()
컬렉션 유형에 대한 콜렉션뿐만 아니라 인덱스에있는 개체 (또는 값 형식)에 대한 참조를 얻을 수 있습니다 :
[1,2,3,4,5].enumerated().forEach{print($0,$1)}
또는
for (c,i) in [1,2,3,4,5].enumerated(){print(c,i)}
또는 (더 짧은 CountableClosedRange
구문)
(1...5).enumerated().forEach{print($0,$1)}
인쇄물:
0 1
1 2
2 3
3 4
4 5
때로는 순수한 Swift 유형 대신 Foundation 유형으로 돌아가 바이트를 절약 할 수 있습니다. NSString
Swift String
유형과 Swift 유형 의 하위 문자열 액세스를 비교하십시오 .
let x:NSString = "hello world"
x.substringToIndex(5) // "hello"
let y = "hello world"
y.substringToIndex(y.startIndex.advancedBy(5)) // "hello"
심지어 선언함으로써 손실 9 개 문자로 x
int로서 NSString
있기 때문에, 당신은, 재단 형식을 사용하여 25 개를 저장 substringToIndex
소요 Int
에 대한 매개 변수로 NSString
대, Index
구조체 ( String.CharacterView.Index
스위프트에 대한) String
유형.
Foundation 유형의 가용성은 여러 플랫폼 (OS X, Linux 등)에 따라 다를 수 있습니다. 대부분의 Foundation 수업은 NSUnimplemented
Swift의 오픈 소스 버전에 있습니다.
.map()
후행 클로저 구문과 결합하면 루프를 강화할 수 있습니다. 반복하고자하는 것들을 배열에 넣은 다음 .map()
각 요소에 대해 몇 가지 작업을 수행 할 수 있습니다.
예를 들어, 우리는 .map()
그 오래된 밤 피즈 버즈를 한 줄에 쓸 수 있습니다 .
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"
대신.