स्विफ्ट में गोल्फिंग के लिए टिप्स


24

स्विफ्ट में कोड-गोल्फिंग के लिए कुछ सुझाव क्या हैं? सुरक्षा पर इसका ध्यान केंद्रित करना मुश्किल लगता है, लेकिन यह थोड़ा सुझाव देता है और इससे भी अधिक उपयोगी है। क्या स्विफ्ट में कोई विशेषताएं हैं जो कुछ अनुप्रयोगों में कोड-गोल्फ में उत्कृष्टता प्राप्त करने में मदद कर सकती हैं?

कृपया प्रति उत्तर एक टिप पोस्ट करें।


11
आप हम पर भरोसा कर सकते हैं - यदि यह सुरक्षित होने के लिए है, तो इसे d̶a̶n ong̶e̶r̶o̶u̶s̶ गोल्फ़ बनाया जाएगा!
कॉनर ओ'ब्रायन

9
उम्मीद है कि कुछ अच्छे सुझाव तेजी से आए।
DJMcMayhem

4
स्विफ्ट गोल्फिंग? मुझे लगा कि गोल्फ धीमा-शांत, शांत खेल होना चाहिए ...
जोजोड्मो

जवाबों:


6

सीमाओं

एक चीज जो वास्तव में मददगार है, वह है परिचालकों ...या ..<ऑपरेटरों का उपयोग करके श्रेणियां बनाना

उदाहरण के लिए

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 प्राप्त करने के लिए

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, तो 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

ऑनलाइन स्विफ्ट चलाना:

हालांकि यह कोशिश करो ऑनलाइन स्विफ्ट का समर्थन नहीं करता है यह अब करता है !


2
पोस्ट के लिए धन्यवाद। मेरी बहुत मदद की। tio.run/nexus अब स्विफ्ट के साथ काम करता है :)
palme

3

try

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?अभिव्यक्ति का मूल्यांकन करेगा niltry!यदि कोई त्रुटि है, तो आपके प्रोग्राम को क्रैश कर देगा, और केवल उन मामलों में उपयोग किया जाना चाहिए जहां कभी भी कोई त्रुटि नहीं होगी।

let regex = try! NSRegularExpression(pattern: "\"((http)s?://.*?)\"", options: [])

try?और लूप try!से कम से कम 13 बाइट बचाएं do-try-catch। ध्यान दें कि आप खाली सरणी ( []) के बजाय विकल्पों के लिए भी पास होने से कम से कम एक और बाइट बचाते हैं 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, +))

और फॉर-इन लूप के साथ सरणी के अंदर तत्वों का उत्पाद प्राप्त करना:

var multiplier = 1
for item in array{
    multiplier *= item
}
print(multiplier)

इसे भी कम किया जा सकता है:

print(array.reduce(1, *))

मैन्युअल रूप से **कॉल करने से आप फ़ंक्शन को घोषित करके अधिक बाइट्स नहीं खोते हैं pow?
जाल

@ JAL हाँ, लेकिन अगर आप 10 बार pow कहते हैं, तो यह कम मात्रा में बाइट्स बचाता है। वास्तव में सर्वश्रेष्ठ गोल्फ तकनीक नहीं है, लेकिन यह सिर्फ एक और संभावित मदद है। यह विशेष रूप से पॉव के लिए नहीं था, लेकिन अन्य प्रचालनों के लिए जैसे कि अभाज्य संख्याओं की खोज करना, यदि आप ऐसा 3 बार करते हैं, तो यह बाइट्स की एक बड़ी मात्रा को बचाता है
श्री एक्सकोडर

2

स्विफ्ट का टर्नरी ऑपरेटर बहुत ही कठिन है: condition ? action : otherकार्रवाई

अगर हालत सच है, एक काम करो, अगर नहीं, तो कुछ और करो।

textColor = bgIsBlack ? .white : .black

यह textColorसफेद बनाता है यदि पृष्ठभूमि काला है, या काला है यदि पृष्ठभूमि किसी अन्य रंग की है।

नील coalescing ऑपरेटर भी मरोड़ रहा है: a ?? b

मान लें कि आप एक निश्चित कुंजी के लिए JSON की जाँच कर रहे हैं ताकि आप शीर्षक पाठ के रूप में कुंजी का मान प्रस्तुत कर सकें। यदि कुंजी मौजूद नहीं है (यानी मान शून्य है), हम शीर्षक डिफ़ॉल्ट पाठ देना चाहते हैं।

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

सबस्ट्रिंग

कभी-कभी, आप शुद्ध स्विफ्ट प्रकारों का उपयोग करने के बजाय फाउंडेशन प्रकारों पर वापस गिरने से बाइट्स बचा सकते हैं। NSStringबनाम एक स्विफ्ट Stringप्रकार के विकल्प तक पहुँचने की तुलना करें :

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

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

यहां तक ​​कि 9 पात्रों xको एक के रूप में घोषित करके खो दिया है NSString, आप फाउंडेशन प्रकार का उपयोग करके 25 अधिक बचाते हैं, चूंकि स्विफ्ट प्रकारों के लिए एक संरचना बनाम ( ) के लिए एक पैरामीटर के रूप में substringToIndexलेता है ।IntNSStringIndexString.CharacterView.IndexString

मुझे ध्यान देना चाहिए कि फाउंडेशन प्रकारों की उपलब्धता कई प्लेटफार्मों (ओएस एक्स, लिनक्स, आदि) में भिन्न हो सकती है। अधिकांश फाउंडेशन कक्षाएं NSUnimplementedस्विफ्ट के ओपन-सोर्स संस्करण में हैं।


2

।नक्शा()

.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को सही करने के लिए उस पर चला सकते हैं , जैसे:

_ = [
        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
क्या forEachआपके दूसरे उदाहरण में इसका उपयोग करना बेहतर नहीं है ? 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भाग को नोटिस करें , जो काफी दिलचस्प है।


हरमन लाउएनस्टीन के उत्तरों में से एक से प्रेरित ।


1

बार-बार स्ट्रिंग्स

दुर्भाग्य से, स्विफ्ट स्ट्रिंग गुणन का समर्थन नहीं करता है *, इसी तरह पायथन। एक अच्छा तरीका जिसे आप इसके बजाय उपयोग कर सकते हैं 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"बजाय।


+1 क्योंकि मेरे पास कोई विचार चर नहीं था, इसलिए मैं इस तरह के शुरुआती अक्षर हो सकता था।
डैनियल

1

आयात

आप 5 बाइट्स के import Foundationसाथ बदल सकते हैं import UIKit, क्योंकि UIKit पहले से ही आयात करता है।


1
आह तुम सही हो। समीक्षा में यह नहीं देखा
mbomb007
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.