Swiftでのゴルフのヒント


24

Swiftでのコードゴルフのヒントは何ですか?安全性に重点を置いているため、ゴルフをするのが難しくなっているように見えますが、ヒントはほとんどなく、さらに便利です。Swiftには、特定のアプリケーションのコードゴルフで優れていると思われる機能がありますか?

回答ごとに1つのヒントを投稿してください。


11
あなたは私たちを頼りにすることができます-それが安全であることを
コナーオブライエン

9
うまくいけば、いくつかの良いヒントがすぐに届きます。
DJMcMayhem

4
迅速なゴルフ?ゴルフはペースの遅い穏やかなゲームだと
思っていた...-ジョジョドモ

回答:


6

範囲

本当に役立つのは、...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)}

4
for n in 0...3{print(a[n])}無効ですか?
ジュリアンウルフ

4

閉鎖:

関数を保持する変数と関数自体を使用する変数を使用すると、次のことができます。

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

地図:

多くの場合returnmap関数でキーワードを使用する必要はありません。

Swift Onlineの実行:

が、それをオンラインで試してみてくださいスウィフトサポートしていません。 それは今ありません


2
投稿いただきありがとうございます。私を大いに助けてくれました。tio.run/nexusがswiftで動作するようになりました:)
パルメ

3

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ます。また[]、オプションの代わりに空の配列()を渡すことにより、少なくとももう1バイトを節約することに注意してくださいnil


3

配列の削減

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手動で呼び出すよりも多くのバイトを失いませんか?
JAL

@JALはい。ただし、powを10回呼び出すと、少量のバイトが節約されます。本当に最高のゴルフテクニックではありませんが、それはもう一つの潜在的な助けです。これは特に、捕虜のためのものが、そのようなあなたはその3倍をすれば、素数の検索など、他の操作のために、それはバイトの膨大な量を保存していなかった
氏Xcoderを

2

スウィフトの三項演算子は非常に簡潔です:condition ? action : otherアクション

条件が真である場合、1つのことを行い、そうでない場合、何か他のことを行います。

textColor = bgIsBlack ? .white : .black

これにより、textColor背景が黒の場合は白、背景が他の色の場合は黒になります。

nil合体演算子はさらに簡潔です: a ?? b

キーの値をタイトルテキストとして表示できるように、特定のキーのJSONをチェックしているとします。キーが存在しない場合(値がnilの場合)、タイトルのデフォルトテキストを指定します。

title = keysValue ?? "Not Available"

2

列挙

コレクションタイプ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

2

部分文字列

純粋なSwift型を使用する代わりに、Foundation型にフォールバックすることでバイトを節約できる場合があります。のサブストリングとNSStringSwift Stringタイプのサブストリングへのアクセスを比較します。

let x:NSString = "hello world"
x.substringToIndex(5) // "hello"

let y = "hello world"
y.substringToIndex(y.startIndex.advancedBy(5)) // "hello"

でも宣言することによって、失われた9つの文字でxNSStringするので、あなたは、財団のタイプを使用して25以上を節約substringToIndex取るIntためのパラメータとしてNSString対、Index構造体(String.CharacterView.Indexスウィフトのための)Stringタイプ。

Foundationタイプの可用性は、複数のプラットフォーム(OS X、Linuxなど)によって異なる場合があることに注意してください。ほとんどのFoundationクラスはNSUnimplemented、Swiftのオープンソースバージョンにあります。


2

。地図()

.map()末尾のクロージャ構文と組み合わせると、forループを強化できます。繰り返したいものを配列に入れて.map()から、各要素に対して何らかのアクションを実行するために使用できます。

たとえば.map()、古い栗、Fizzbuzzを1行で書くのに使用できます。

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 }

1
forEach2番目の例で使用する方が良いと思いませんか? map繰り返しのショートカットとしてではなく、配列の内容の変換に実際に使用する必要があります。この場合、結果は破棄されます。
JAL

1

タプルを使用した制御フロー構造でのゴルフ変数の割り当て

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の 回答の 1つに触発されました。


1

繰り返し文字列

残念ながら、Swiftは*Pythonと同様に、との文字列乗算をサポートしていません。代わりに使用できる良い方法はですがString(repeating:count:)、残念ながらそれは実際にはゴルフではありません。これら2つのアプローチを比較してください。

var a=String(repeating:"abc",count:3)

そして

var a="";for _ in 0..<3{a+="abc"}

2つ目は数バイト短くなりますが、クロージャーでは使用できません...さらに良いことに、クロージャーでも機能します。

(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"代わりに。


+1は、変数がそのような初期化子になる可能性があるという考えがなかったためです。
ダニエル

1

インポート

UIKitはFoundationを既にインポートimport Foundationしているimport UIKitため、5バイト短く置き換えることができます。


1
ああ、あなたは正しい。レビューでそれを見ませんでした
mbomb007
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.