ईसीएमएस्क्रिप्ट 6 और इसके बाद के संस्करण में गोल्फ के लिए टिप्स


88

यह अन्य "टिप्स इन गोल्फिंग फॉर <...>" के समान है, लेकिन विशेष रूप से ECMAScript 6 और इसके बाद के संस्करण में जावास्क्रिप्ट में नई सुविधाओं को लक्षित करना है।

जावास्क्रिप्ट स्वाभाविक एक बहुत वर्बोज़ भाषा, है function(){}, .forEach(), श्रेणी, श्रेणी के लिए सरणी जैसी वस्तु, आदि, आदि के लिए स्ट्रिंग परिवर्तित सुपर bloats और गोल्फ के लिए स्वस्थ नहीं हैं।

दूसरी ओर, ES6 + में कुछ सुपर काम सुविधाएँ और कम पदचिह्न हैं। x=>y, [...x]आदि इसके कुछ उदाहरण हैं।

कृपया कुछ अच्छी ट्रिक पोस्ट करें जो आपके कोड से उन कुछ अतिरिक्त बाइट्स को हटाने में मदद कर सकती हैं।

नोट: ES5 के लिए ट्रिक पहले से ही जावास्क्रिप्ट में गोल्फ के लिए टिप्स में उपलब्ध हैं ; इस धागे के उत्तर केवल ईएस 6 और भविष्य के ईएस संस्करणों में उपलब्ध ट्रिक्स पर ध्यान देना चाहिए।

हालांकि, यह धागा उन उपयोगकर्ताओं के लिए भी है जो वर्तमान में ES5 सुविधाओं का उपयोग करके गोल्फ कर रहे हैं। उत्तर में ES5 कोडिंग की अपनी शैली के लिए ES6 सुविधाओं को समझने और उन्हें मैप करने में मदद करने के लिए युक्तियां भी हो सकती हैं।

जवाबों:


42

फैला हुआ संचालक ...

स्प्रेड ऑपरेटर अल्पविराम से अलग सूची में एक सरणी मान को परिवर्तित करता है।

केस 1 का प्रयोग करें:

सीधे एक सरणी का उपयोग करें जहां एक फ़ंक्शन किसी सूची की अपेक्षा करता है

list=[1,2,3]
x=Math.min(...list)
list=[10,20], a.push(...list) // similar to concat()

केस 2 का प्रयोग करें:

एक पुनरावृत्त से एक सरणी शाब्दिक बनाएँ (आमतौर पर एक स्ट्रिंग)

[...'buzzfizz'] // -> same as .split('')

केस 3 का उपयोग करें:

किसी फ़ंक्शन के लिए चर की संख्या की घोषणा करें

F=(...x) => x.map(v => v+1)
// example: F(1,2,3) == [2,3,4]

देखें मोज़िला डॉक


3
अब मेरा यहां पर पतन हो गया है। जाहिर है किसी ने इस टिप में बहुत कुछ गलत लिखा है, एक टिप्पणी छोड़ने और समझाने के लिए बहुत शर्म आ रही है ...
edc65

यह ठीक लग रहा है। शायद यह अर्धविराम की कमी थी? ;) (btw, आप इसे बाकी मापदंडों के रूप में भी इस्तेमाल कर सकते हैं, जैसे रूबी में
छप

आप यह जोड़ सकते हैं कि फ़ंक्शन हस्ताक्षर में इसका उपयोग मामला भी है :)
फेलिक्स डॉम्बेक

मेंटलिक का मतलब नीचा दिखाना नहीं था
स्टेन

@StanStrum ऐसा होता है। मैं इस पोस्ट के लिए एक छोटा सा अपडेट करूंगा ताकि आप अंततः अपना वोट बदल सकें (या आप पहले से ही?)
edc65

21

जब मैंने ज्वाइन किया तब से ट्रिक्स यहाँ सीखे

मेरी प्राथमिक प्रोग्रामिंग भाषा JS है और ज्यादातर ES6 है। चूँकि मैं एक सप्ताह पहले इस साइट से जुड़ा था, इसलिए मैंने साथी सदस्यों से बहुत उपयोगी तरकीबें सीखी हैं। मैं उनमें से कुछ को यहाँ जोड़ रहा हूँ। सारा श्रेय समुदाय को जाता है।

एरो फ़ंक्शंस और लूप्स

हम सभी जानते हैं कि एरो फ़ंक्शंस बहुत सारे बाइट्स को बचाते हैं

function A(){do something} // from this
A=a=>do something // to this

लेकिन आपको कुछ बातों का ध्यान रखना होगा

  • ,यानी (a=b,a.map(d))- का उपयोग करके कई कथनों को क्लब करने की कोशिश करें , यहां जो मूल्य वापस किया जाता है वह अंतिम अभिव्यक्ति हैa.map(d)
  • यदि आपका do somethingभाग एक से अधिक कथन है, तो आपको आसपास के {}कोष्ठकों को जोड़ना होगा ।
  • यदि आसपास के {}ब्रैकेट हैं, तो आपको एक स्पष्ट रिटर्न स्टेटमेंट जोड़ना होगा।

जब आप लूप शामिल करते हैं तो उपरोक्त कई बार सही होता है। तो कुछ इस तरह:

u=n=>{for(s=[,1,1],r=[i=1,l=2];c=l<n;i+=!c?s[r[l++]=i]=1:1)for(j of r)c-=j<i/2&s[i-j];return n>1?r:[1]}

यहां मैं वापसी के कारण कम से कम 9 पात्रों को बर्बाद कर रहा हूं। यह अनुकूलित किया जा सकता है।

  • छोरों से बचने की कोशिश करें। का प्रयोग करें .mapया .everyया .someबजाय। ध्यान दें कि यदि आप उसी सरणी को बदलना चाहते हैं जिसे आप मैप कर रहे हैं, तो यह विफल हो जाएगा।
  • एक बंद तीर फ़ंक्शन में लूप लपेटें, मुख्य तीर फ़ंक्शन को एकल कथन के रूप में परिवर्तित करना।

तो ऊपर बन जाता है:

u=n=>(s=>{for(r=[i=1,l=2];c=l<n;i+=!c?s[r[l++]=i]=1:1)for(j of r)c-=j<i/2&s[i-j]})([,1,1])|n>1?r:[1]

हटाए गए वर्ण: {}return

जोड़े गए वर्ण: (){}>|

ध्यान दें कि मैं क्लोजर विधि को कैसे कॉल करता हूं, जो चर को सही ढंग से पॉप्युलेट करता है nऔर फिर चूंकि क्लोजर विधि कुछ भी वापस नहीं कर रही है (अर्थात वापस लौट रही है undefined), मैं बिटवाइज़ करता हूं या इसे छोड़ देता हूं और nबाहरी एरो फ़ंक्शन के एकल स्टेटमेंट में सभी को वापस कर देता हूंu

कमांड और अर्धविराम

उन्हें कभी भी ऐसा करने से बचें,

यदि आप एक लूप में वेरिएबल की घोषणा कर रहे हैं, या पिछले अनुभाग में उल्लेख किया गया है, ,तो एक स्टेटमेंट एरो फ़ंक्शंस का उपयोग करने के लिए अलग-अलग स्टेटमेंट का उपयोग करके , तो आप उन से बचने के लिए ,या ;उन कुछ अंतिम बाइट्स को शेव करने के लिए कुछ सुंदर निफ्टी ट्रिक्स का उपयोग कर सकते हैं ।

इस कोड पर विचार करें:

r=v=>Math.random()*100|0;n=r();m=r();D=v=>A(n-x)+A(m-y);d=0;do{g();l=d;d=D();....

यहाँ, मैं कई वैरिएबल्स को इनिशियलाइज़ करने के लिए बहुत सारे तरीके बता रहा हूँ। प्रत्येक आरंभीकरण एक ,या का उपयोग कर रहा है ;। इसे फिर से लिखा जा सकता है:

r=v=>Math.random()*100|0;n=r(m=r(d=0));D=v=>A(n-x)+A(m-y);do{d=D(l=d,g());....

ध्यान दें कि मैं इस तथ्य का उपयोग कैसे करता हूं कि विधि इसके लिए पारित चर को परेशान नहीं करती है और उस तथ्य का उपयोग 3 बाइट्स को दाढ़ी बनाने के लिए करता है।

विविध

.search के बजाय .indexOf

दोनों एक ही परिणाम देते हैं, लेकिन searchकम है। हालांकि खोज एक नियमित अभिव्यक्ति की उम्मीद करती है, इसलिए इसका उपयोग बुद्धिमानी से करें।

`टेम्पलेट स्ट्रिंग्स`

जब आप कुछ शर्तों के आधार पर एक या एक से अधिक स्ट्रिंग भागों को समेटना चाहते हैं, तो ये बहुत ही आसान हैं।

JS में आउटपुट करने के लिए निम्न उदाहरण लें

(f=x=>alert("(f="+f+")()"))()

बनाम

(f=x=>alert(`(f=${f})()`))()

एक टेम्पलेट स्ट्रिंग में, जो दो बैकक्वॉट्स (`) के अंदर एक स्ट्रिंग है, एक के अंदर कुछ भी ${ }एक कोड के रूप में माना जाता है और स्ट्रिंग में परिणामी उत्तर को सम्मिलित करने के लिए मूल्यांकन किया जाता है।

मैं बाद में कुछ और ट्रिक्स पोस्ट करूंगा। हैप्पी गोल्फिंग!


1
.Search कम है, जब संभव हो इसका उपयोग करें! लेकिन यह .indexOf के समान नहीं है। .search एक regexpनहीं, एक स्ट्रिंग चाहता है । कोशिश करें'abc'.search('.')
edc65

@ edc65 अपडेट किया गया!
ऑप्टिमाइज़र

आप उदाहरण विधियों के साथ मूल सरणी को संशोधित कर सकते हैं। दूसरा वर्तमान सूचकांक है, और तीसरा सरणी पुनरावृत्त किया जा रहा है।
इसियाह मीडोज

8
"एक सप्ताह पहले साइट में शामिल हो गए" - 21.4k प्रतिनिधि ...
GamrCorps

2
साथ ही .map, पुनरावृत्ति एक और तकनीक है जो कभी-कभी एक forलूप को एक अभिव्यक्ति में बदलने में आपकी मदद कर सकती है ।
नील

20

संपत्ति शॉर्टहैंड का उपयोग करना

संपत्ति आशुलिपि आपको चर के मानों को चर सेट करने की अनुमति देती है:

a=r[0];b=r[1] // ES5
[a,b]=r       // ES6 - 6 bytes saved

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

a=r[0],b=r[2] // ES5
[a,,b]=r      // ES6 - 5 bytes saved

आप इसका उपयोग चर को उलटने के लिए भी कर सकते हैं:

c=a,a=b,b=c // ES5 - uses extra variable
[b,a]=[a,b] // ES6 - not shorter, but more flexible

आप इसका उपयोग slice()फ़ंक्शंस को छोटा करने के लिए भी कर सकते हैं ।

z = [1, 2, 3, 4, 5];

a=z.slice(1) // a = [2,3,4,5]; ES5
[,...a]=z    // a = [2,3,4,5]; ES6

आधार रूपांतरण

ES6 फॉर्म बेस -2 (बाइनरी) और बेस -8 (ऑक्टल) को दशमलव में बदलने के लिए बहुत छोटा रास्ता प्रदान करता है:

0b111110111 // == 503
0o767       // == 503

+एक बाइनरी, ऑक्टल या हेक्स स्ट्रिंग को दशमलव संख्या में बदलने के लिए इस्तेमाल किया जा सकता है। आप उपयोग कर सकते हैं 0b, 0oऔर 0xक्रमशः, द्विआधारी, अष्टाधारी, और हेक्स के लिए .:

parseInt(v,2) // ES5
+('0b'+v)     // ES6 - 4 bytes saved; use '0o' for octal and '0x' for hex
'0b'+v-0      // Shorter, but may not work in all cases
              // You can adapt this your case for better results

यदि आप इसे> 7 बार उपयोग कर रहे हैं, तो इसका उपयोग करना parseIntऔर इसका नाम बदलना कम होगा :

(p=parseInt)(v,2)

अब के pलिए इस्तेमाल किया जा सकता है parseInt, आप लंबे समय में कई बाइट्स की बचत।


आधार रूपांतरण चाल अच्छा है, लेकिन इसकी अधिक संभावना है कि रूपांतरण संख्या एक शाब्दिक के बजाय एक चर के रूप में होगी, इस स्थिति में, यह बहुत लंबा हो जाता है।
ऑप्टिमाइज़र

1
'0x'+v-0और भी छोटा है, लेकिन कुछ परिदृश्यों में भी काम नहीं कर सकता है।
ETHproductions

1
वैसे, 0767(ES5 0o767) नोटेशन (ES6) से कम है ।
कैमिलो मार्टिन

@CamiloMartin 0767एक गैर-मानक एक्सटेंशन है, और इसे सख्त मोड में स्पष्ट रूप से मना किया गया है।
ओरिऑल

1
@ ओरोल सख्त मोड एक बुरा मेम था। इसने प्रदर्शन में मदद नहीं की, वास्तव में आपको अच्छा कोड लिखने के लिए मजबूर नहीं किया, और वैसे भी कभी भी डिफ़ॉल्ट नहीं बनेगा। 0-सुपरक्षित अष्टक शाब्दिक कहीं भी नहीं जा रहे हैं, और के रूप में मान्य पारिस्थितिकी के रूप में कर रहे हैं 0o
कैमिलो मार्टिन

19

कार्यों के साथ स्ट्रिंग टेम्पलेट्स का उपयोग करना

जब आपके पास तर्कों के रूप में एक स्ट्रिंग के साथ एक फ़ंक्शन होता है। ()यदि आपके पास कोई अभिव्यक्ति नहीं है तो आप इसे छोड़ सकते हैं :

join`` // Works
join`foobar` // Works
join`${5}` // Doesn't work 

9
चेतावनी दी है, यह वास्तव में एक सरणी गुजरता है। fun`string` रूप में ही है fun(["string"]), नहीं fun("string")। यह उन कार्यों के लिए ठीक है जो स्ट्रिंग को पसंद करते हैं alert, जैसे , लेकिन अन्य लोगों के लिए यह समस्या पैदा कर सकता है। अधिक जानकारी के लिए
एमडीएन

5
त्वरित संदर्भ चीज़: fun`foo${1}bar${2}bazकॉल करने के बराबर हैfun(["foo","bar","baz"],1,2)
Cycece

14

ऐरे कॉम्प्रिहेंशन (फ़ायरफ़ॉक्स 30-57)

नोट: सरणी समझ को कभी भी मानकीकृत नहीं किया गया था, और फ़ायरफ़ॉक्स 58 के साथ अप्रचलित कर दिया गया था। अपने स्वयं के जोखिम पर उपयोग करें।


मूल रूप से, ECMAScript 7 युक्ति में नई सरणी-आधारित सुविधाओं का एक समूह था। हालांकि इनमें से अधिकांश यह अंतिम रूप संस्करण में नहीं किया, फायरफॉक्स समर्थन (ईडी) संभवतः इन सुविधाओं में से सबसे बड़ी: फैंसी नई वाक्य रचना कि जगह ले सकता है .filterऔर .mapसाथ for(a of b)वाक्य रचना। यहाँ एक उदाहरण है:

b.filter(a=>/\s/.test(a)).map(a=>a.length)
[for(a of b)if(/\s/.test(a))a.length]

जैसा कि आप देख सकते हैं, दो पंक्तियाँ बिलकुल भिन्न नहीं हैं, दूसरे में भारी कीवर्ड और तीर फ़ंक्शंस शामिल नहीं हैं। लेकिन यह केवल आदेश के लिए खाता है .filter().map(); .map().filter()इसके बजाय अगर आपके पास क्या होता है ? वास्तव में यह स्थिति पर निर्भर करता है:

b.map(a=>a[0]).filter(a=>a<'['&&a>'@')
[for(a of b)if(a<'['&&a>'@')a[0]]

b.map(a=>c.indexOf(a)).filter(a=>a>-1)
[for(a of b)if((d=c.indexOf(a))>-1)d]

b.map(a=>a.toString(2)).filter(a=>/01/.test(a))
[for(a of b)if(/01/.test(c=a.toString(2)))c]

या अगर आप या तो चाहते हैं तो क्या होगा ? खैर, यह आमतौर पर कम ठीक निकलता है:.map .filter

b.map(a=>a.toString(2))
[for(a of b)a.toString(2)]

b.filter(a=>a%3&&a%5)
[for(a of b)if(a%3&&a%5)a]

इसलिए मेरी सलाह है कि आप जहाँ भी आमतौर पर उपयोग करेंगे .map और जहाँ भी हो .filter, लेकिन एक या दूसरे नहीं, बल्कि सरणी समझ का उपयोग करें ।

स्ट्रिंग कॉम्प्रिहेंशन

ES7 समझ के बारे में एक अच्छी बात यह है कि, सरणी-विशिष्ट कार्यों जैसे कि .mapऔर .filter, उन्हें किसी भी उपयोग करने योग्य वस्तु पर इस्तेमाल किया जा सकता है , न कि केवल सरणियों के विपरीत । यह विशेष रूप से उपयोगी है जब तार के साथ काम करते हैं। उदाहरण के लिए, यदि आप प्रत्येक वर्ण cको एक स्ट्रिंग में चलाना चाहते हैं c.charCodeAt():

x=>[...x].map(c=>c.charCodeAt())
x=>[for(c of x)c.charCodeAt()]

यह दो बाइट्स काफी छोटे पैमाने पर सहेजे गए हैं। और क्या होगा यदि आप कुछ पात्रों को एक स्ट्रिंग में फ़िल्टर करना चाहते हैं? उदाहरण के लिए, यह केवल बड़े अक्षर रखता है:

x=>[...x].filter(c=>c<'['&&c>'@')
x=>[for(c of x)if(c<'['&&c>'@')c]

हम्म, यह कोई छोटा नहीं है। लेकिन अगर हम दोनों को जोड़ दें:

x=>[...x].filter(c=>c<'['&&c>'@').map(c=>c.charCodeAt())
x=>[for(c of x)if(c<'['&&c>'@')c.charCodeAt()]

वाह, एक पूरे 10 बाइट्स बचाए!

स्ट्रिंग की समझ का एक और फायदा यह है कि हार्डकोडेड स्ट्रिंग्स एक अतिरिक्त बाइट को बचाते हैं, क्योंकि आप बाद में स्पेस को छोड़ सकते हैं of:

x=>[...'[](){}<>'].map(c=>x.split(c).length-1)
x=>[for(c of'[](){}<>')x.split(c).length-1]

x=>[...'[](){}<>'].filter(c=>x.split(c).length>3)
x=>[for(c of'[](){}<>')if(x.split(c).length>3)c]

इंडेक्सिंग

ऐरे कॉम्प्रिहेंशन को स्ट्रिंग / एरे में करंट इंडेक्स पाने में थोड़ी मुश्किल होती है, लेकिन यह किया जा सकता है:

a.map((x,i)=>x+i).filter ((x,i)=>~i%2)
[for(x of(i=0,a))if(++i%2)x+i-1]

मुख्य बात यह है कि यह सुनिश्चित करने के लिए कि सूचकांक हर बार बढ़ जाता है , न कि केवल एक शर्त पूरी होने पर।

जेनरेटर की समझ

जनरेटर की समझ में मूल रूप से सरणी समझ के रूप में एक ही वाक्यविन्यास है; कोष्ठक के साथ कोष्ठक को बदलें:

x=>(for(c of x)if(c<'['&&c>'@')c.charCodeAt())

यह एक जनरेटर बनाता है जो एक सरणी के समान ही कार्य करता है, लेकिन यह एक और उत्तर के लिए एक कहानी है।

सारांश

मूल रूप से, हालांकि समझ आम तौर पर की तुलना में कम है .map().filter(), यह सब स्थिति की बारीकियों के लिए नीचे आता है। इसे दोनों तरीकों से आज़माना सबसे अच्छा है और देखें कि कौन सा बेहतर काम करता है।

पुनश्च एक और समझ से संबंधित टिप या इस उत्तर को बेहतर बनाने का एक तरीका सुझाएं!


यहाँ उन श्रेणियों के लिए एक चाल है जो कुछ और पात्रों को (x,y)=>[...Array(y-x)].map(a=>x++)
बचाएंगे

2
0 से x तक की सीमा बनाने के लिए आप 11 बाइट्स काट सकते हैं:x=>[...Array(x).keys()]
Mwr247

अंतिम समझ के लिए वहाँ एक: n=>[for(x of Array(n).keys())if(/1/.test(x))x](7 बाइट्स बचाता है)
Mwr247

@ Mwr247 वास्तव में, मैं अब देख सकता हूं कि आम तौर पर अन्य अच्छे ES6 फीचर्स के साथ रेंज कम नहीं हैं। मैं इसके बजाय स्ट्रिंग्स पर एक सेक्शन में जोड़ूंगा, और आपको सीमाएं संभालने दूंगा।
ETHproductions

यह ध्यान देने योग्य है कि ऐरे कॉम्प्रिहेंशन को जावास्क्रिप्ट के सभी हाल के संस्करणों से हटा दिया गया है और हटा दिया गया है। विषय पर MDN डॉक्स देखें ।
कीफेर राउरके

13

ES6 में फ़ंक्शन अभिव्यक्तियाँ तीर संकेतन का उपयोग करती हैं, और यह ES5 संस्करण के साथ तुलना करने पर बाइट को बचाने में बहुत मदद करता है:

f=function(x,y){return x+y}
f=(x,y)=>x+y

यदि आपके फ़ंक्शन में केवल एक पैरामीटर है, तो आप दो बाइट्स को सहेजने के लिए कोष्ठकों को छोड़ सकते हैं:

f=x=>x+1

यदि आपके फ़ंक्शन में कोई पैरामीटर नहीं है, तो इसे घोषित करें जैसे कि यह एक बाइट को बचाने के लिए था:

f=()=>"something"
f=x=>"something"

खबरदार: एरो फ़ंक्शंस बिल्कुल वैसे ही नहीं हैं function () {}। इसके लिए नियम thisअलग हैं (और बेहतर IMO)। डॉक्स देखें


2
लेकिन जब आप गोल्फ-आईएनजी होते हैं, तो आप आमतौर पर thisआदि की परवाह नहीं करते हैं
ऑप्टिमाइज़र

1
आम तौर पर नहीं, लेकिन यह एक चेतावनी है, जिसे आप कभी नहीं जान सकते हैं कि यह कब आता है। लैम्बदास के लिए उत्पादन में इस बंधन को कार्य-स्थानीय की आवश्यकता नहीं होना भी अधिक सामान्य है।
इसियाह मीडोज

इसके अलावा, यदि आप अपने सभी तर्कों को लेना चाहते हैं, तो आप "बाकी" तर्क सुविधा का उपयोग कर सकते हैं, उदाहरण के लिए, f=(...x)=>x ऐसा होगा f(1,2,3) => [1,2,3]
कॉनर ओ'ब्रायन

1
यहाँ इस साइट के लिए एक टिप दी गई है: यदि आप किसी ऐसे फ़ंक्शन के साथ उत्तर दे रहे हैं, जो फॉर्म को लेता है तो (x,y)=>...आप बाइट को करीने से सहेज कर रख सकते हैंx=>y=>...
Cyoce

12

evalकई कथनों और ए के साथ एरो फ़ंक्शंस के लिए उपयोग करनाreturn

अधिक हास्यास्पद चालों में से एक है जो मैंने ठोकर खाई है ...

एक साधारण तीर फ़ंक्शन की कल्पना करें, जिसे कई कथनों की आवश्यकता है और ए return

a=>{for(o="",i=0;i<a;i++)o+=i;return o}

एक एकल फ़ंक्शन को स्वीकार करने वाला एक सरल कार्य a, जो सभी पूर्णांकों में पुनरावृत्त करता है [0, a), और आउटपुट स्ट्रिंग के अंत में उन्हें टैक करता है o, जो वापस आ जाता है। उदाहरण के लिए, इसे 4पैरामीटर के रूप में कॉल करने से उपज होगी 0123

ध्यान दें कि इस तीर फ़ंक्शन को ब्रेसिज़ में लपेटा जाना था {}, और return oअंत में है।

यह पहला प्रयास 39 बाइट्स में होता है ।

बुरा नहीं है, लेकिन उपयोग करके eval, हम इसे सुधार सकते हैं।

a=>eval('for(o="",i=0;i<a;i++)o+=i;o')

इस फ़ंक्शन ने कोड को एक में लपेटकर evalऔर evalमूल्यांकन में अंतिम कथन बनाकर ब्रेसेस और रिटर्न स्टेटमेंट को हटा दिया o। यह evalवापसी का कारण बनता है o, जो बदले में फ़ंक्शन को वापस करने का कारण बनता है o, क्योंकि यह अब एक ही बयान है।

38 बाइट्स में इस बेहतर प्रयास का वज़न होता है , मूल से एक बाइट की बचत होती है।

लेकिन रुकिए, और भी है! उनके अंतिम विवरण का मूल्यांकन करने के लिए, जो भी कथन हैं वे वापस आ जाते हैं। इस मामले में, का o+=iमूल्यांकन करता है o, इसलिए हमें इसकी आवश्यकता नहीं है ;o! (धन्यवाद, edc65!)

a=>eval('for(o="",i=0;i<a;i++)o+=i')

यह अंतिम प्रयास केवल 36 बाइट्स का वजन करता है - मूल पर 3 बाइट बचत!


यह तकनीक किसी भी सामान्य मामले में विस्तारित की जा सकती है जहां एक तीर फ़ंक्शन को एक मान लौटाने की आवश्यकता होती है और कई कथन होते हैं (जिसे अन्य साधनों द्वारा संयोजित नहीं किया जा सकता है)

b=>{statement1;statement2;return v}

हो जाता है

b=>eval('statement1;statement2;v')

एक बाइट की बचत।

यदि इसका statement2मूल्यांकन किया जाए v, तो यह हो सकता है

b=>eval('statement1;statement2')

कुल 3 बाइट्स की बचत।


1
मुझे लगता है, सिर्फ एक अनाम फ़ंक्शन लिखना और भी कम हो सकता है
डाउनगेट

@vihan हाँ, इन दोनों कार्यों को प्रत्येक को 2 बाइट बचाने के लिए अनाम बनाया जा सकता है। एक बाइट बचत अभी भी हालांकि खड़ा है।
जिक्र

1
लेकिन इससे भी बेहतर: eval ने अंतिम अभिव्यक्ति वापस लौटा दी, इसलिए आपको ज़रूरत नहीं है ;o- इसे आज़माएं:a=>eval('for(o="",i=0;i<a;i++)o+=i')
edc65

4
लेकिन टेम्पलेट तार!
कॉनर ओ'ब्रायन

1
@ C @O'Bʀɪᴇɴ यह समझाने के लिए ध्यान दें कि संदर्भ के रूप में उदाहरण फ़ंक्शन का उपयोग करके टेम्पलेट स्ट्रिंग्स कैसे काम करेंगे?
वैलीवेस्ट

10

"\ N" पर टेम्पलेट स्ट्रिंग नई लाइनों को प्राथमिकता दें

यह आपके कोड में एक भी नई पंक्ति वर्ण पर भुगतान करना शुरू कर देगा। एक उपयोग मामला हो सकता है:

(16 बाइट्स)

array.join("\n")

(15 बाइट्स)

array.join(`
`)

अपडेट: आप टैग किए गए टेम्पलेट स्ट्रिंग्स (धन्यवाद, edc65!) के कारण ब्रेसिज़ भी छोड़ सकते हैं।

(13 बाइट्स)

array.join`
`

5
लेकिन इससे भी बेहतर, आप कोष्ठक से बच सकते हैं। डॉक्स ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) यह देखने के लिए पढ़ें कि क्यों
edc65

ठीक है। धन्यवाद, मैंने इसे जोड़ा है।
चिरू

9

भरने Arrays - स्थैतिक मूल्यों और गतिशील रेंज

मैंने मूल रूप से इन्हें समझ के तहत टिप्पणियों के रूप में छोड़ दिया, लेकिन चूंकि यह पोस्ट मुख्य रूप से समझ पर केंद्रित थी, इसलिए मुझे लगा कि यह इसे अपनी जगह देना अच्छा होगा।

ES6 ने हमें छोरों के उपयोग के बिना स्थिर मूल्यों के साथ सरणियों को भरने की क्षमता दी:

// ES5
function(x){for(i=0,a=[];i<x;i++)a[i]=0;return a}

// ES6
x=>Array(x).fill(0)

दोनों मान 0 से भरे, लंबाई x की एक सरणी लौटाते हैं।

यदि आप गतिशील मानों के साथ सरणियाँ भरना चाहते हैं (जैसे 0 से एक सीमा ... x) हालाँकि, परिणाम थोड़ा लंबा है (हालाँकि अभी भी पुराने तरीके से छोटा है):

// ES5
function(x){for(i=0,a=[];i<x;i++)a[i]=i;return a}

// ES6
x=>Array(x).fill().map((a,i)=>i)

दोनों लंबाई x की एक सरणी लौटाते हैं, मान 0 से शुरू होता है और x-1 में समाप्त होता है।

कारण है कि तुम .fill()वहाँ की जरूरत है क्योंकि बस एक सरणी को आरंभीकृत करने से आप इसे मैप नहीं कर पाएंगे। यह कहना है, कर x=>Array(x).map((a,i)=>i)एक खाली सरणी वापस आ जाएगी। आप प्रसार की आवश्यकता को भर भी सकते हैं (और इस तरह इसे और भी छोटा कर सकते हैं)

x=>[...Array(x)]

प्रसार ऑपरेटर और .keys()फ़ंक्शन का उपयोग करके , आप अब एक छोटी 0 ... x श्रेणी बना सकते हैं:

x=>[...Array(x).keys()]

यदि आप x ... y, या पूरी तरह से एक विशेष श्रेणी (जैसे कि संख्याएँ) से कोई कस्टम श्रेणी चाहते हैं, तो आप फैलाने वाले ऑपरेटर से छुटकारा पा सकते हैं .keys()और उपयोग कर सकते हैं .map(), या उपयोग कर सकते हैं .filter():

// Custom range from x...y
(x,y)=>[...Array(y-x)].map(a=>x++)

// Even numbers (using map)
x=>[...Array(x/2)].map((a,i)=>i*2)

// Even numbers (using filter)
x=>[...Array(x).keys()].filter(a=>~a%2)

यहां दूसरे उदाहरण के लिए एक सुझाव दिया गया है: x=>Array(x).fill(i=0).map(a=>i++)इसके अलावा, मुझे यकीन नहीं है कि 0 में .fill(0)आवश्यक है। क्या आपने इसके बिना कोशिश की है?
ETHproductions

@ETHproductions आप सही हैं, मैं भूल गया कि 0 को मानचित्र से पहले भरने की आवश्यकता नहीं है। हालांकि यह आपके सुझाए गए एक से 1 वर्ण को छोटा बनाता है, इसलिए मैं इसे ऐसे ही रखूंगा। धन्यवाद!
Mwr247

इसके अलावा, अंतिम उदाहरण के लिए, a=>a%2-1ठीक काम करता है, जैसा कि करता है a=>a%2<1
ETHproductions

1
एक नई चाल जो मैंने सीखी है: [...Array(x)]साथ ही साथ काम करती है Array(x).fill(), और 2 बाइट्स कम है। x=>[...Array(x)].map((a,i)=>i)
ETHproductions

1
@yonatanmn बहुत अच्छा! केवल टिप्पणियां 1 होंगी) 1/4उदाहरण छोटा लिखा जाएगा [0,0,0,0], और 2) कठोर कार्य विशिष्ट कार्यान्वयन हैं, इसलिए एक विश्वसनीय लंबाई ( Mapक्रोम में 32 बाइट्स, लेकिन फ़ायरफ़ॉक्स में 36 बाइट्स) नहीं लौटेगी ।
Mwr247

9

एरो फ़ंक्शंस में रिटर्निंग वैल्यूज़

यह सामान्य ज्ञान है कि यदि एक भी कथन एरो फंक्शन डिक्लेरेशन का अनुसरण करता है, तो यह उस स्टेटमेंट का परिणाम देता है:

a=>{return a+3}
a=>a+3

-7 बाइट्स

इसलिए जब संभव हो, एक में कई कथनों को मिलाएं। यह सबसे आसानी से कोष्ठक के साथ बयानों को घेरकर और उन्हें अल्पविराम से अलग करके किया जाता है:

a=>{r=0;a.map(n=>r+=n);return r}
a=>(r=0,a.map(n=>r+=n),r)

-8 बाइट्स

लेकिन अगर केवल दो बयान हैं, तो उन्हें &&या उनके साथ जोड़ना आमतौर पर संभव है (और छोटा) ||:

a=>{r=0;a.map(n=>r+=n);return r}

// - Use && because map always returns an array (true)
// - declaration of r moved into unused map argument to make it only 2 statements
a=>a.map(n=>r+=n,r=0)&&r

-9 बाइट्स

अंत में यदि आप मानचित्र (या समान) का उपयोग कर रहे हैं और आपको एक नंबर वापस करने की आवश्यकता है और आप गारंटी दे सकते हैं कि मानचित्र कभी भी एक नंबर के साथ 1-लंबाई सरणी नहीं लौटाएगा, तो आप उस नंबर को वापस कर सकते हैं |:

a=>{a=b=0;a.map(n=>(a+=n,b-=n));return a/b}

// - {} in map ensures it returns an array of undefined, so the | will make the returned
//   array cast from [ undefined, undefined, undefined ] to ",," to NaN to 0 and 0|n = n,
//   if the map returned [ 4 ] it would cast from [ 4 ] to "4" to 4 and make it 4|n
a=>a.map(n=>{a+=n,b-=n},a=b=0)|a/b

उस अंतिम उदाहरण में, आपको यह भी सुनिश्चित करने की आवश्यकता है कि संख्या हमेशा पूर्णांक होगी।
ETHproductions

8

रैंडम टेम्पलेट-स्ट्रिंग हैक

यह फ़ंक्शन दो स्ट्रिंग्स को राइफल करता है (अर्थात में बदल जाता "abc","de"है "adbec"):

f=(x,y)=>String.raw({raw:x},...y)

ध्यान दें कि यह केवल तभी काम करता है जब इससे xअधिक लंबा हो y। यह कैसे काम करता है, आप पूछते हैं? String.rawएक टेम्प्लेट टैग के लिए डिज़ाइन किया गया है, जैसे:

String.raw`x: ${x}\ny: ${y}\nx + y: ${x + y}`

यह मूल रूप से कहता है String.raw(["x: ", "\ny: ", "\nx + y: ", ""], x, y, x + y), हालांकि यह इतना आसान नहीं है। टेम्पलेट सरणी में एक विशेष rawगुण भी है , जो मूल रूप से सरणी की एक प्रति है, लेकिन कच्चे तार के साथ। String.raw(x, ...args)मूल रूप से रिटर्न x.raw[0] + args[0] + x.raw[1] + args[1] + x.raw[2] + ...और इतने पर जब तक xआइटम से बाहर चलाता है।

तो अब हम जानते हैं कि कैसे String.rawकाम करता है, हम इसे अपने लाभ के लिए उपयोग कर सकते हैं:

f=(x,y)=>String.raw({raw:x},...y)                   // f("abc", "de") => "adbec"
f=x=>String.raw({raw:x},...[...x].keys())           // f("abc") => "a0b1c"
f=(x,y)=>String.raw({raw:x},...[...x].fill(y))      // f("abc", " ") => "a b c"

बेशक, उस अंतिम एक के लिए, f=(x,y)=>x.split``.join(y)रास्ता छोटा है, लेकिन आपको यह विचार मिलता है।

यहाँ कुछ रिफ़्लिंग फ़ंक्शंस हैं जो काम करते हैं xऔर अगर yसमान लंबाई के हैं:

f=(x,y)=>String.raw({raw:x.match(/.?/g)},...y)
f=(x,y)=>String.raw({raw:x},...y)+y.slice(-1)  // Only works if x.length == y.length

आप String.raw MDN के बारे में अधिक जान सकते हैं ।


7

पुनरावृत्ति के साथ गोल्फ कैसे करें

पुनरावृत्ति, हालांकि सबसे तेज़ विकल्प नहीं है, बहुत कम बार होता है। आम तौर पर, पुनरावृत्ति सबसे कम होती है यदि समाधान चुनौती के एक छोटे हिस्से के समाधान को सरल बना सकता है, खासकर अगर इनपुट एक संख्या या एक स्ट्रिंग है। उदाहरण के लिए, यदि f("abcd")इसकी गणना की जा सकती है "a"और f("bcd"), आमतौर पर पुनरावृत्ति का उपयोग करना सबसे अच्छा है।

उदाहरण के लिए, तथ्यात्मक को लें:

n=>[...Array(n).keys()].reduce((x,y)=>x*++y,1)
n=>[...Array(n)].reduce((x,_,i)=>x*++i,1)
n=>[...Array(n)].reduce(x=>x*n--,1)
n=>{for(t=1;n;)t*=n--;return t}
n=>eval("for(t=1;n;)t*=n--")
f=n=>n?n*f(n-1):1

इस उदाहरण में, पुनरावृत्ति स्पष्ट रूप से किसी अन्य विकल्प की तुलना में कम है।

कैसे चारकोड के योग के बारे में:

s=>[...s].map(x=>t+=x.charCodeAt(),t=0)|t
s=>[...s].reduce((t,x)=>t+x.charCodeAt())
s=>[for(x of(t=0,s))t+=x.charCodeAt()]|t  // Firefox 30+ only
f=s=>s?s.charCodeAt()+f(s.slice(1)):0

यह एक पेचीदा मामला है, लेकिन हम देख सकते हैं कि जब इसे सही तरीके से लागू किया जाता है, तो पुनरावृत्ति 4 बाइट्स बचाती है .map

अब विभिन्न प्रकार के पुनरावर्तन पर नजर डालते हैं:

पूर्व प्रत्यावर्तन

यह आमतौर पर सबसे छोटी प्रकार की पुनरावृत्ति है। इनपुट दो भागों में विभाजित है aऔर b, और समारोह के साथ कुछ की गणना करता है aऔर f(b)। हमारे तथ्यात्मक उदाहरण पर वापस जा रहे हैं:

f=n=>n?n*f(n-1):1

इस मामले में, aहै n , bहै n-1 , और दिए गए मान है a*f(b)

महत्वपूर्ण नोट: सभी पुनरावर्ती कार्यों में इनपुट छोटा होने पर पुनरावर्तन को रोकने का एक तरीका होना चाहिए । फैक्टोरियल फंक्शन में, इसे नियंत्रित किया जाता है n? :1, अर्थात यदि इनपुट 0 है , तो फिर से कॉल किए बिना 1 लौटें f

पोस्ट-प्रत्यावर्तन

पुनरावृत्ति पूर्व पुनरावृत्ति के समान है, लेकिन थोड़ा अलग है। इनपुट दो भागों में विभाजित है aऔर b, और समारोह के साथ कुछ की गणना करता है a, तो कहता है f(b,a)। दूसरे तर्क में आमतौर पर एक डिफ़ॉल्ट मान (यानी f(a,b=1)) होता है।

पूर्व-पुनरावृत्ति अच्छा है जब आपको अंतिम परिणाम के साथ कुछ विशेष करने की आवश्यकता होती है। उदाहरण के लिए, यदि आप संख्या 1 का भाज्य चाहते हैं:

f=(n,p=1)=>n?f(n-1,n*p):p+1

फिर भी, हालांकि, पोस्ट- किसी अन्य फ़ंक्शन के भीतर पूर्व-पुनरावृत्ति का उपयोग करने से हमेशा छोटा नहीं होता है:

n=>(f=n=>n?n*f(n-1):1)(n)+1

तो यह कब कम है? आप देख सकते हैं कि इस उदाहरण में पोस्ट-रिकरशन को फ़ंक्शन तर्कों के आसपास कोष्ठक की आवश्यकता होती है, जबकि पूर्व-पुनरावृत्ति नहीं हुई थी। आम तौर पर, यदि दोनों समाधानों को तर्कों के चारों ओर कोष्ठकों की आवश्यकता होती है, तो पुनरावृत्ति 2 बाइट्स के आसपास होती है:

n=>!(g=([x,...a])=>a[0]?x-a.pop()+g(a):0)(n)
f=([x,...a],n=0)=>a[0]?f(a,x-a.pop()+n):!n

( इस उत्तर से लिए गए कार्यक्रम )

सबसे छोटा उपाय कैसे खोजे

आमतौर पर सबसे छोटी विधि खोजने का एकमात्र तरीका उन सभी को आज़माना है। यह भी शामिल है:

  • लूप्स
  • .map(तार के लिए, या तो [...s].mapया s.replace; संख्या के लिए है, तो आप कर सकते हैं एक श्रेणी बनाएं )
  • ऐरे की समझ
  • पूर्व-पुनरावर्तन (कभी-कभी इन विकल्पों में से एक के भीतर)
  • पोस्ट-प्रत्यावर्तन

और ये सिर्फ सबसे आम समाधान हैं; सबसे अच्छा समाधान इनमें से एक संयोजन हो सकता है, या यहां तक ​​कि कुछ पूरी तरह से अलग भी हो सकता है । सबसे छोटा उपाय खोजने का सबसे अच्छा तरीका सब कुछ करने की कोशिश करना है


1
इसके मूल्य के लिए +1, और मुझे zootopia के लिए एक और +1 जोड़ना होगा
edc65

7

कम करने के तरीके .replace


यदि आप एक स्ट्रिंग में दूसरे के साथ एक सटीक प्रतिस्थापन के सभी उदाहरणों को बदलना चाहते हैं, तो स्पष्ट तरीका होगा:

f=s=>s.replace(/l/g,"y") // 24 bytes
f("Hello, World!")       // -> "Heyyo, Woryd!"

हालाँकि, आप 1 बाइट कम कर सकते हैं:

f=s=>s.split`l`.join`y`  // 23 bytes
f("Hello, World!")       // -> "Heyyo, Woryd!"

ध्यान दें कि यह अब छोटा नहीं है यदि आप gध्वज के अलावा किसी भी regex सुविधाओं का उपयोग करना चाहते हैं । हालाँकि, यदि आप किसी चर के सभी उदाहरणों की जगह ले रहे हैं, तो यह आमतौर पर बहुत छोटा होता है:

f=(s,c)=>s.replace(RegExp(c,"g"),"") // 36 bytes
f=(s,c)=>s.split(c).join``           // 26 bytes
f("Hello, World!","l") // -> "Heo, Word!"

कभी-कभी आप एक स्ट्रिंग में प्रत्येक चार पर मैप करना चाहते हैं, प्रत्येक को किसी और चीज़ के साथ बदल सकते हैं। मैं अक्सर खुद को ऐसा करते हुए पाता हूं:

f=s=>s.split``.map(x=>x+x).join`` // 33 bytes
f=s=>[...s].map(x=>x+x).join``    // 30 bytes
f("abc") // -> "aabbcc"

हालांकि, .replaceलगभग हमेशा छोटा होता है:

f=s=>s.replace(/./g,x=>x+x)  // 27 bytes
f=s=>s.replace(/./g,"$&$&")  // Also works in this particular case

अब, यदि आप एक स्ट्रिंग में प्रत्येक चार्ट पर मैप करना चाहते हैं, लेकिन परिणामी स्ट्रिंग की परवाह नहीं करते हैं, .mapतो आमतौर पर बेहतर होता है क्योंकि आप छुटकारा पा सकते हैं .join``:

f=s=>s.replace(/./g,x=>t+=+x,t=0)&&t // 36 bytes
f=s=>[...s].map(x=>t+=+x,t=0)&&t     // 32 bytes
f("12345")  // -> 15

आखिरी मामले के लिए, यदि केवल एक रेगेक्स (जैसे /\w/g) से मेल खाने वाले कुछ पात्र रुचि रखते हैं, तो इस डेमो के रूप में प्रतिस्थापित का उपयोग करना बेहतर होगा ।
शायरु असकोटो

6

RegEx के साथ शाब्दिक लेखन eval

रेगेक्स कंस्ट्रक्टर लंबे नाम के कारण बहुत भारी हो सकता है। इसके बजाय, ईवैल और बैकटिक्स के साथ एक शाब्दिक लिखें:

eval(`/<${i} [^>]+/g`)

यदि चर iइसके बराबर है foo, तो यह उत्पन्न होगा:

/<foo [^>]+/g

यह बराबर है:

new RegExp("<"+i+" [^>]+","g")

आप String.rawबार-बार बैकस्लैश से बचने के लिए उपयोग करने से भी बच सकते हैं\

eval(String.raw`/\(?:\d{4})?\d{3}\d{3}\d{3}\d{3}\d{3}\d{3}\d{4}/g`)

यह आउटपुट होगा:

/(?:\d{4})?\d{3}\d{3}\d{3}/g

जो बराबर है:

RegExp("\\(?:\\d{4})?\\d{3}\\d{3}\\d{3}\\d{3}\\d{3}\\d{3}\\d{4}","g")

याद रखो!

String.rawबहुत सारे बाइट्स लेता है और जब तक आपके पास कम से कम नौ बैकस्लैश String.rawनहीं होंगे , तब तक लंबा होगा।


आपको newवहां की आवश्यकता नहीं है , इसलिए निर्माणकर्ता का उपयोग वास्तव में दूसरे उदाहरण के लिए कम है
ऑप्टिमाइज़र

5

.forEachबनाम forलूप्स

हमेशा .mapकिसी भी लूप के लिए पसंद करें। आसान, तुरंत बचत।


a.map(f)
for(x of a)f(x);
for(i=0;i<a.length;)f(a[i++]);
  • मूल के लिए कुल 8 बाइट्स
  • 8 बाइट्स बनाम के लिए ( 50% की कमी)
  • लूप के लिए सी-स्टाइल बनाम 22 बाइट्स ( 73% की कमी)

a.map(x=>f(x,0))
for(x of a)f(x,0);
for(i=0;i<a.length;)f(a[i++],0);
  • मूल के लिए कुल 16 बाइट्स
  • 2 बाइट्स के लिए बचाया ( 11% की कमी)
  • लूप के लिए सी-स्टाइल बनाम 16 बाइट्स ( 50% की कमी)

a.map((x,i)=>f(x,i,0))
for(i in a)f(a[i],i,0);
for(i=0;i<a.length;)f(a[i],i++,0);
  • मूल के लिए कुल 22 बाइट्स
  • 1 बाइट बनाम बनाम में ( 4% की कमी)
  • 11 बाइट्स लूप के लिए सी-स्टाइल बनाम 33% की कमी

a.map(x=>f(x)&g(x))
for(x of a)f(x),g(x);
for(i=0;i<a.length;)f(x=a[i++]),g(x);
  • मूल के लिए कुल 19 बाइट्स
  • 2 बाइट्स बनाम के लिए ( 10% की कमी)
  • लूप के लिए सी-स्टाइल से बचाए गए 18 बाइट्स ( 49% की कमी)

5

पुनरावृत्ति में असिंचित काउंटरों का उपयोग करना

नोट : कड़ाई से बोलना, यह ES6 के लिए विशिष्ट नहीं है। यह ES6 में उपयोग और दुरुपयोग पुनरावृत्ति के लिए अधिक समझ में आता है, हालांकि, तीर कार्यों की संक्षिप्त प्रकृति के कारण।


यह एक पुनरावर्ती फ़ंक्शन के पार आना आम है, जो kप्रारंभ में शून्य पर सेट किए गए एक काउंटर का उपयोग कर रहा है और प्रत्येक पुनरावृत्ति पर बढ़ा हुआ है:

f = (…, k=0) => [do a recursive call with f(…, k+1)]

कुछ परिस्थितियों में, इस तरह के काउंटर के आरंभीकरण को छोड़ना और उसके k+1साथ प्रतिस्थापित करना संभव है -~k:

f = (…, k) => [do a recursive call with f(…, -~k)]

यह ट्रिक आमतौर पर 2 बाइट्स बचाता है

यह क्यों और कब काम करता है?

सूत्र जो इसे संभव बनाता है ~undefined === -1। इसलिए, पहली पुनरावृत्ति पर, -~kइसका मूल्यांकन किया जाएगा 1। अगले पुनरावृत्तियों पर, -~kअनिवार्य रूप से समतुल्य है -(-k-1)जो बराबर है k+1, कम से कम पूर्णांक के लिए सीमा [0… 2 31 -1] में।

हालाँकि आपको यह सुनिश्चित करना होगा कि k = undefinedपहली पुनरावृत्ति होने से फ़ंक्शन का व्यवहार बाधित नहीं होगा। आपको विशेष रूप से ध्यान में रखना चाहिए कि अधिकांश अंकगणितीय कार्यों में शामिल undefinedहोगा NaN

उदाहरण 1

सकारात्मक पूर्णांक को देखते हुए n, यह फ़ंक्शन सबसे छोटे पूर्णांक के लिए दिखता है जो kविभाजित नहीं होता है n:

f=(n,k=0)=>n%k?k:f(n,k+1)   // 25 bytes

इसे छोटा किया जा सकता है:

f=(n,k)=>n%k?k:f(n,-~k)     // 23 bytes

यह काम करता है क्योंकि n % undefinedहै NaN, जो मिथ्या है। यह पहली पुनरावृत्ति पर अपेक्षित परिणाम है।

[मूल उत्तर से लिंक करें]

उदाहरण # 2

सकारात्मक पूर्णांक को देखते हुए n, यह फ़ंक्शन पूर्णांक की pतरह दिखता है (3**p) - 1 == n:

f=(n,p=0,k=1)=>n<k?n>k-2&&p:f(n,p+1,k*3)  // 40 bytes

इसे छोटा किया जा सकता है:

f=(n,p,k=1)=>n<k?n>k-2&&p:f(n,-~p,k*3)    // 38 bytes

यह काम करता है क्योंकि pपहली पुनरावृत्ति ( n<kगलत होने) पर इसका उपयोग नहीं किया जाता है ।

[मूल उत्तर से लिंक करें]


5

ES6 कार्य

गणित

Math.cbrt(x)पात्रों को बचाता है Math.pow(x,1/3)

Math.cbrt(x)
Math.pow(x,1/3)

3 चरस बच गई

Math.hypot(...args)उपयोगी है जब आप वर्ग के वर्ग की राशि के वर्गमूल की जरूरत है। ईएस 5 कोड बनाना, जो बिल्ट-इन का उपयोग करने की तुलना में बहुत कठिन है।

समारोह Math.trunc(x)सहायक नहीं होगा, जैसा x|0कि कम है। (धन्यवाद Mwr247!)

कई गुण हैं जो ES5 में बहुत सारे कोड लेते हैं, लेकिन ES6 में आसान है:

  • Math.acosh, asinh, atanh, cosh, sinh, tanh। त्रिकोणमितीय कार्यों के हाइपरबोलिक समतुल्य की गणना करता है।
  • Math.clz32। ES5 में करना संभव हो सकता है, लेकिन अब आसान है। संख्या के 32-बिट प्रतिनिधित्व में शून्य का नेतृत्व करता है।

वहाँ एक बहुत अधिक कर रहे हैं, तो मैं बस कुछ सूचीबद्ध करने के लिए जा रहा हूँ:
Math.sign, Math.fround, Math.imul, Math.log10, Math.log2, Math.log1p


Math.trunc(x)से चार गुना अधिक लंबा है x|0
Mwr247

@ mwr247: ठीक है, अपडेट करेंगे।
ev3commander

यहाँ इन कार्यों के एक जोड़े के लिए सबसे छोटा ES5 समकक्ष मैं के बारे में पता है: Math.hypot(a,b) => Math.sqrt(a*a+b*b)(3 बाइट्स लंबे समय तक और अधिक तर्क के साथ भी लंबे समय तक हो जाता है), Math.sign(a) => (a>0)-(a<0)(1 बाइट कम, लेकिन कुछ मामलों में कोष्ठकों आसपास की जरूरत है; काम नहीं कर सकता साथ NaN)
ETHproductions

@ETHproductions आपको हाइप के लिए (es5 वर्कअराउंड) तर्कों की आवश्यकता है। और क्या आप सुनिश्चित हैं कि Math.sign के लिए समाधान -0 के लिए काम करता है? (यह -0 पर लौटना चाहिए)
ev3commander

1
@ ev3commander ये सिर्फ उनके संबंधित ES6 समकक्षों के लिए इन-लाइन रिप्लेसमेंट के रूप में हैं, इसलिए उन्हें 99% उपयोग के लिए घटाया जाता है। वास्तव में इन कार्यों को फिर से बनाने के लिए बहुत अधिक कोड की आवश्यकता होगी। इसके अलावा, मुझे -0 के लिए एक विशेष मामले की आवश्यकता के लिए कोई कारण नहीं दिखता है, क्योंकि (एएफएआईके) को -0 को मैन्युअल रूप से निर्दिष्ट करने के अलावा -0 प्राप्त करने का कोई तरीका नहीं है, और कोड-गोल्फ के भीतर व्यावहारिक रूप से इसका कोई उपयोग नहीं है। लेकिन उन चीजों को इंगित करने के लिए धन्यवाद।
ETHproductions

5

के लिए छोटे निरंतर पर्वतमाला का अनुकूलन map()

प्रसंग

map()for[0 ..एन-1]

for(i = 0; i < 10; i++) {
  do_something_with(i);
}

या तो द्वारा प्रतिस्थापित किया जा सकता है:

[...Array(10).keys()].map(i => do_something_with(i))

या अधिक सामान्यतः:

[...Array(10)].map((_, i) => do_something_with(i))

Array(N)एन

[0 ..एन-1]

मैं

N           | Method                               | Example                         | Length
------------+--------------------------------------+---------------------------------+-------
N ≤ 6       | use a raw array of integers          | [0,1,2,3].map(i=>F(i))          | 2N+10
N = 7       | use either a raw array of integers   | [0,1,2,3,4,5,6].map(i=>F(i))    | 24
            | or a string if your code can operate | [...'0123456'].map(i=>F(i))     | 23
            | with characters rather than integers |                                 |
8 ≤ N ≤ 9   | use scientific notation 1e[N-1]      | [...1e7+''].map((_,i)=>F(i))    | 24
N = 10      | use scientific notation 1e9          | [...1e9+''].map((_,i)=>F(i))    | 24
            | or the ES7 expression 2**29+'4' if   | [...2**29+'4'].map(i=>F(i))     | 23
            | the order doesn't matter and your    |                                 |
            | code can operate with characters     |  (order: 5,3,6,8,7,0,9,1,2,4)   |
            | rather than integers                 |                                 |
11 ≤ N ≤ 17 | use scientific notation 1e[N-1]      | [...1e12+''].map((_,i)=>F(i))   | 25
N = 18      | use the fraction 1/3                 | [...1/3+''].map((_,i)=>F(i))    | 24
N = 19      | use the fraction 1/6                 | [...1/6+''].map((_,i)=>F(i))    | 24
20 ≤ N ≤ 21 | use scientific notation 1e[N-1]      | [...1e20+''].map((_,i)=>F(i))   | 25
N = 22      | use scientific notation -1e20        | [...-1e20+''].map((_,i)=>F(i))  | 26
23 ≤ N ≤ 99 | use Array(N)                         | [...Array(23)].map((_,i)=>F(i)) | 27

NB : कॉलबैक कोड की लंबाई की F(i)गणना नहीं की जाती है।

[1..9]

[1..9]

[...17**6+'8'].map(i=>F(i))  // order: 2,4,1,3,7,5,6,9,8; length: 23

काउंटर के बिना अनुकूलन

एन

N           | Method                               | Example                         | Length
------------+--------------------------------------+---------------------------------+-------
N ≤ 5       | use a raw array of integers          | [0,0,0,0].map(_=>F())           | 2N+10
6 ≤ N ≤ 10  | use scientific notation 1e[N-1]      | [...1e7+''].map(_=>F())         | 20
11 ≤ N ≤ 17 | use scientific notation 1e[N-1]      | [...1e12+''].map(_=>F())        | 21
N = 18      | use the fraction 1/3                 | [...1/3+''].map(_=>F())         | 20
N = 19      | use the fraction 1/6                 | [...1/6+''].map(_=>F())         | 20
20 ≤ N ≤ 21 | use scientific notation 1e[N-1]      | [...1e20+''].map(_=>F())        | 21
N = 22      | use scientific notation -1e20        | [...-1e20+''].map(_=>F())       | 22
23 ≤ N ≤ 99 | use Array(N)                         | [...Array(23)].map(_=>F())      | 23

NB : कॉलबैक कोड की लंबाई की F()गणना नहीं की जाती है।


नहीं 2**26होना चाहिए 2**29?
शैगी

@ शैगी हेक। अच्छी पकड़!
अरनुलद

अपने आप को संपादित नहीं करना चाहता था क्योंकि मुझे कोड-अंधापन मिला है! : डी
झबरा

का उपयोग करते हुए .keys(), आपको एक लैम्ब्डा की आवश्यकता नहीं है:[...Array(10).keys()].map(do_something_with)
लंबे समय से लाजुली

@ लॉन्ग-लाजुली अगर आपको एक लैम्ब्डा की जरूरत नहीं है और सिर्फ एक रेंज चाहिए, तो आपको शायद मैप की भी जरूरत नहीं है ...
Arnauld

4

विनाशकारी कार्य

ES6 विनाशकारी असाइनमेंट के लिए नए सिंटैक्स का परिचय देता है, अर्थात टुकड़ों में एक मूल्य काटकर और प्रत्येक टुकड़े को एक अलग चर में असाइन करना। कुछ उदाहरण निम्नलिखित हैं:

तार और सरणियाँ

a=s[0];b=s[1];       // 14 bytes
[a,b]=s;             //  8 bytes

a=s[0];s=s.slice(1); // 20 bytes
a=s.shift();         // 12 bytes, only works if s is an array
[a,...s]=s;          // 11 bytes, converts s to an array

वस्तुओं

a=o.asdf;b=o.bye;c=o.length; // 28 bytes
{asdf:a,bye:b,length:c}=o;   // 26 bytes

a=o.a;b=o.b;c=o.c; // 18 bytes
{a,b,c}=o;         // 10 bytes

इन असाइनमेंट का उपयोग फंक्शन पैरामीटर्स में भी किया जा सकता है:

f=a=>a[0]+a[1]+a[2]
f=([a,b,c])=>a+b+c

f=b=>b[1]?b[0]+f(b.slice(1)):b[0]*2
f=b=>b[1]?b.shift()+f(b):b[0]*2
f=([a,...b])=>b[0]?a+f(b):a*2

4

फिर भी बचने का एक और तरीका return

तुम्हें पता है कि आप कई बयानों और एक वापसी के साथ तीर कार्यों के लिए eval का उपयोग करना चाहिए । कुछ असामान्य मामलों में आप एक आंतरिक सबफंक्शन का उपयोग करके अधिक बचत कर सकते हैं।

मैं असामान्य इसलिए कहता हूं

  1. लौटाया गया परिणाम लूप में स्पष्ट अंतिम अभिव्यक्ति नहीं होना चाहिए

  2. लूप से पहले कम से कम 2 अलग-अलग इनिशियलाइज़ेशन होने चाहिए

इस मामले में आप रिटर्न के बिना एक आंतरिक सबफंक्शन का उपयोग कर सकते हैं, एक पैरामीटर के रूप में पारित प्रारंभिक मूल्यों में से एक है।

उदाहरण a से b तक की श्रेणी में मानों के लिए एक्सप फ़ंक्शन के योग का पारस्परिक पता लगाएं।

लंबा रास्ता - 55 बाइट्स

(a,b)=>{for(r=0,i=a;i<=b;i++)r+=Math.exp(i);return 1/r}

Eval के साथ - 54 बाइट्स

(a,b)=>eval("for(r=0,i=a;i<=b;i++)r+=Math.exp(i);1/r")

एक आंतरिक फ़ंक्शन के साथ - 53 बाइट्स

(a,b)=>(i=>{for(r=0;i<=b;i++)r+=Math.exp(i)})(a)||1/r

ध्यान दें कि कम रेंज की सीमा की आवश्यकता के बिना a, मैं i और r के इनिशियलाइज़ेशन को मर्ज कर सकता हूं और इवैल संस्करण छोटा है।


अपने नमूने में रखने के लिए कोई आवश्यकता नहीं हैa
l4m2

@ l4m2 मैं आपकी बात नहीं मान सकता, कृपया मदद करें ...
edc65

(i,b)=>{for(r=0;i<=b;i++)r+=Math.exp(i);return 1/r}
l4m2

@ l4m2 उह सही, return a/rएक बेहतर उदाहरण होगा
edc65

1
eval अभी भी बेहतर है (a,b)=>1/eval("for(r=0,i=a;i<=b;i++)r+=Math.exp(i)")और इस मामले में(i,b)=>1/eval("for(r=0;i<=b;)r+=Math.exp(i++)")
JayXon

4

डाइएडिक और पुनरावर्ती कार्यों के लिए करी सिंटैक्स का उपयोग करना

विधायी कार्य

जब भी कोई फ़ंक्शन बिना किसी डिफ़ॉल्ट मान के ठीक दो तर्क लेता है, तो क्यूरिंग सिंटैक्स का उपयोग करके एक बाइट बचाता है।

इससे पहले

f =
(a,b)=>a+b  // 10 bytes

के साथ बुलाया गया f(a,b)

उपरांत

f =
a=>b=>a+b   // 9 bytes

के साथ बुलाया गया f(a)(b)

नोट : मेटा में यह पोस्ट इस सिंटैक्स की वैधता की पुष्टि करता है।

पुनरावर्ती कार्य

जब एक पुनरावर्ती फ़ंक्शन कई तर्क लेता है, तो करी सिंटैक्स का उपयोग कुछ बाइट्स को भी बचा सकता है, लेकिन केवल प्रत्येक पुनरावृत्ति के बीच उनमें से कुछ को अपडेट करने की आवश्यकता होती है।

उदाहरण

निम्न फ़ंक्शन श्रेणी में सभी पूर्णांकों के योग की गणना करता है [a,b]:

f=(a,b)=>a>b?0:b+f(a,b-1)   // 25 bytes

क्योंकि aपूरी प्रक्रिया के दौरान अपरिवर्तित रहता है, हम 3 बाइट्स का उपयोग करके बचा सकते हैं:

f =                         // no need to include this assignment in the answer anymore
a=>F=b=>a>b?0:b+F(b-1)      // 22 bytes

नोट : जैसा कि नील ने टिप्पणियों में देखा है, यह तथ्य कि एक तर्क को पुनरावर्ती कार्य के लिए स्पष्ट रूप से पारित नहीं किया जाता है, इसका मतलब यह नहीं है कि इसे अपरिवर्तनीय माना जाना चाहिए। यदि आवश्यक हो, तो हम aफ़ंक्शन कोड के साथ a++, a--या जो भी समान सिंटैक्स संशोधित कर सकते हैं ।


अंतिम उदाहरण के रूप में लिखा जा सकता है a=>F=b=>a>b?0:a+++F(b), aप्रत्येक पुनरावर्ती कॉल के लिए संशोधन । यह उस मामले में मदद नहीं करता है, लेकिन यह अधिक तर्कों वाले मामलों में बाइट्स को बचा सकता है।
नील

हे, मैं इस :-) के लिए एक टिप लिखने के बारे में सोच रहा था :-)
ETHproductions

4

परिक्षण-परीक्षण कार्य

निम्नलिखित 28-बाइट फ़ंक्शन trueप्राइम नंबर के लिए और falseगैर-primes के लिए लौटाता है :

f=(n,x=n)=>n%--x?f(n,x):x==1

यह आसानी से अन्य चीजों की गणना करने के लिए संशोधित किया जा सकता है। उदाहरण के लिए, यह 39-बाइट फ़ंक्शन किसी संख्या की तुलना में कम या बराबर primes की संख्या की गणना करता है:

f=(n,x=n)=>n?n%--x?f(n,x):!--x+f(n-1):0

यदि आपके पास पहले से ही एक चर है nजिसे आप primality के लिए जांचना चाहते हैं, तो primality फ़ंक्शन को थोड़ा सरल किया जा सकता है:

(f=x=>n%--x?f(x):x==1)(n)

यह काम किस प्रकार करता है

f = (         // Define a function f with these arguments:
  n,          //   n, the number to test;
  x = n       //   x, with a default value of n, the number to check for divisibility by.
) =>
  n % --x ?   //   If n is not divisible by x - 1,
  f(n, x)     //     return the result of f(n, x - 1).
              //   This loops down through all numbers between n and 0,
              //     stopping when it finds a number that divides n.
  : x == 1    //   Return x == 1; for primes only, 1 is the smallest number
              //     less than n that divides n.
              //   For 1, x == 0; for 0, x == -1.

नोट: यह 12345 जैसे पर्याप्त बड़े इनपुट के साथ कॉल करने पर "बहुत अधिक पुनरावृत्ति" त्रुटि के साथ विफल हो जाएगा। आप इसे एक लूप के साथ प्राप्त कर सकते हैं:

f=n=>eval('for(x=n;n%--x;);x==1')

1
लेकिन एक इनपुट के लिए बहुत अधिक पुनरावृत्ति के साथ असफल
रहें

x==1शायद x<2बचत के लिए हो सकता है।
कैलकुलेटर

@CalculatorFeline धन्यवाद, लेकिन फिर इसे के लिए विफल रहता है 1या 0(क्योंकि xहो सकता है 0या -1क्रमश)
ETHproductions

कुछ मामलों में उपयोगी हो सकता है। इसके अलावा, !~-x-0 बाइट्स के लिए।
कैलक्यूलेटरफ्लेन

3

Array#concat() और फैला हुआ ऑपरेटर

यह काफी हद तक स्थिति पर निर्भर करता है।


कई सरणियों का संयोजन।

जब तक क्लोनिंग न हो तब तक फंक्शन फ़ंक्शन को प्राथमिकता दें।

0 बाइट्स बच गए

a.concat(b)
[...a,...b]

3 बाइट बर्बाद

a.concat(b,c)
[...a,...b,...c]

3 बाइट बच गईं

a.concat()
[...a]

6 बाइट बच गईं

// Concatenate array of arrays
[].concat.apply([],l)
[].concat(...l)

पहले से मौजूद सरणी का उपयोग करना पसंद करते हैं Array#concat()

आसान 4 बाइट्स बचाए गए

[].concat(a,b)
a.concat(b)

3

मध्यवर्ती परिणाम लौटाएं

आप जानते हैं कि अल्पविराम ऑपरेटर का उपयोग करके आप अंतिम मूल्य पर लौटने वाले भावों के अनुक्रम को निष्पादित कर सकते हैं। लेकिन शाब्दिक सरणी सिंटैक्स का दुरुपयोग करते हुए, आप किसी भी मध्यवर्ती मान को वापस कर सकते हैं। यह उदाहरण के लिए .map () में उपयोगी है।

// capitalize words
// f is a flag indicating if prev char is space
[...x].map(c=>(f?c=c.toUpperCase():0,f=c<'!',c),f=1).join('')

// shortened to ...
[...x].map(c=>[f?c.toUpperCase():c,f=c<'!'][0],f=1).join('')

3
याद रखें, निश्चित रूप से, यह .join('')हो सकता है.join``
साइओस

3

फ़ंक्शन पैरामीटर डिफ़ॉल्ट सेट करें

($,a,b,_)=>_!=undefined?'asdf':_ // before
($,a,b,_)=>_!=[]._?'asdf':_ // before, but a bit golfed
($,a,b,_='asdf')=>_ // after

यह वास्तव में उपयोगी है ...

हालांकि, यह समझना सुनिश्चित करें कि _=>_||'asdf'जब आप केवल फ़ंक्शन में एक (उपयोगी) तर्क पास कर रहे हैं, तो कुछ कम है।


1
मैं ध्यान देता हूं कि OR _=>_||'asdf'का उपयोग आमतौर पर ज्यादातर मामलों में कम होता है
Downgoat

@Downgoat मैं ध्यान देता हूँ कि (खाली स्ट्रिंग) के "asdf"इनपुट के लिए रिटर्न ""
ETHproductions

2
ध्यान दें कि डिफॉल्ट का मूल्यांकन तब किया जाता है जब भी तर्क होता है undefined, भले ही आप उस मूल्य को स्पष्ट रूप से पास करते हों। उदाहरण के लिए, [...Array(n)].map((a,b,c)=>b)हमेशा के undefinedलिए गुजरता है a, और इसलिए आप इसके लिए एक डिफ़ॉल्ट मान प्रदान कर सकते हैं (हालांकि के संदर्भ में नहीं b)।
नील

3

उपयोग evalतीर के कार्यों के लिए ब्रेसिज़ के बजाय का

एरो फंक्शन कमाल के हैं। वे फॉर्म लेते हैं x=>y, जहां xएक तर्क है और yवापसी मूल्य है। हालाँकि, यदि आपको एक नियंत्रण संरचना का उपयोग करने की आवश्यकता है, जैसे कि while, आपको ब्रेसिज़ लगाना होगा, जैसे =>{while(){};return}। हालाँकि, हम इसे प्राप्त कर सकते हैं; सौभाग्य से, evalफ़ंक्शन एक स्ट्रिंग लेता है, उस स्ट्रिंग का जेएस कोड के रूप में मूल्यांकन करता है, और अंतिम मूल्यांकित अभिव्यक्ति देता है । उदाहरण के लिए, इन दोनों की तुलना करें:

x=>{while(foo){bar};return baz} // before
x=>eval('while(foo){bar};baz')  // after
//                            ^

हम अपने कोड को और छोटा करने के लिए इस अवधारणा के विस्तार का उपयोग कर सकते हैं: evalनियंत्रण संरचनाओं की दृष्टि में , अपनी अंतिम मूल्यांकित अभिव्यक्ति को भी वापस करते हैं। उदाहरण के लिए:

x=>{while(foo)bar++;return bar} // before
x=>eval('while(foo)++bar')      // after
//                        ^^^^^

3

ES6 में गोल्फ लॉजिकल ऑपरेशन

"ग्लो (S6)"

सामान्य तर्क

आप बयान का निर्माण किया है कहते हैं sऔर t। देखें कि क्या आप निम्न में से किसी भी प्रतिस्थापन का उपयोग कर सकते हैं:

Traditional conjuction: s&&t
Equivalent conjuction: s*t OR s&t

Traditional disjunction: s||t
Equivalent disjunction: s+t OR s|t

(यदि ऑर्डर गलत है तो ये काम नहीं कर सकते हैं; अर्थात +और *निम्न क्रम की पूर्ववर्ती स्थिति है ||और&& करते हैं।)

इसके अलावा, यहां कुछ आसान तार्किक अभिव्यक्तियां दी गई हैं:

  • या तो sया tसही / XOR है:s^t
  • sऔर tएक ही सत्य मूल्य हैं: !s^tयाs==t

तर्क तर्क

सभी aसंतुष्ट हालत के सदस्य p:

a.every(p)                             // 10 bytes (11 bytes saved)
a.map(x=>c&=p(x),c=1)                  // 21 bytes (16 bytes saved)
for(i=0,c=1;i<a.length;c&=p(a[i++]));  // 37 bytes (hideously long)

aसंतोषजनक स्थिति के कम से कम एक सदस्य p:

a.some(p)                            // 9  bytes (13 bytes saved)
a.map(x=>c|=p(x),c=0)                // 21 bytes (14 bytes saved)
for(i=c=0;i<a.length;c|=p(a[i++]));  // 35 bytes (just please no)

aसंतुष्ट स्थिति का कोई सदस्य नहीं p:!a.some(p)

तत्व eसरणी में मौजूद है a:

a.includes(e)                        // 13 bytes, standard built-in
~a.indexOf(e)                        // 13 bytes, "traditional" method
a.find(x=>e==x)                      // 15 bytes, find (ES6)
a.some(x=>x==e)                      // 15 bytes, some (ES5)
(a+"").search(e)                     // 16 bytes, buggy
a.filter(t=>t==e).length             // 24 bytes, no reason to use this
for(i=c=0;i<a.length;c+=e==a[i++]);  // 35 bytes, super-traditional

तत्व eहै नहीं सरणी में मौजूद हैं a:

!a.includes(e)
!~a.indexOf(e)
a.every(t=>t!=e)
!a.filter(t=>t==e).length
for(i=0,c=1;i<a.length;c*=e!=a[i++]);

मैं आम तौर पर उपयोग करने &&और ||के रूप में x?y:xऔर x?x:yक्रमश:। लेकिन मैं देख सकता हूं कि अधिक तर्क-आधारित कार्यक्रमों में यह कैसे उपयोगी होगा। के साथ एक समस्या +यह होगी कि उदा 3और -3दोनों सत्य हैं, लेकिन 3+-3ऐसा नहीं है।
2

@ETHproductions आह, आप सही हैं; यह एक एज केस है। -भी काम कर सकता है, अगर s != t
कॉनर ओ'ब्रायन

a.filter(t=>t==e).length==a.lengthगलत है। यह होना चाहिए!a.filter(t=>t==e).length
ETHproductions

@ETHproductions आप सही हैं!
कॉनर ओ'ब्रायन ने

3

छोटा किया हुआ फ़ंक्शन कॉल करता है

यदि आपने एक लंबे-ईश नाम के साथ किसी फ़ंक्शन को बार-बार कॉल किया है, जैसे कि कैनवास हेरफेर:

c.lineTo(0,100);c.lineTo(100,100);c.lineTo(100,0);c.lineto(0,0);c.stroke()

पारंपरिक रूप से इसे छोटा करने के लिए फ़ंक्शन नाम को उपनाम देना होगा:

c[l='lineTo'](0,100);c[l](100,100);c[l](100,0);c[l](0,0);c.stroke()

यदि आपके पास पर्याप्त कॉल हैं, तो एक बेहतर तरीका एक फ़ंक्शन बनाना है जो आपके लिए काम करता है:

l=(x,y)=>c.lineTo(x,y);l(0,100);l(100,100);l(100,0);l(0,0);c.stroke()

यदि फ़ंक्शन के अधिकांश कॉल जंजीर हैं, तो आप फ़ंक्शन को स्वयं वापस कर सकते हैं, जिससे आप प्रत्येक क्रमिक दो बाइट्स काट सकते हैं:

l=(x,y)=>c.lineTo(x,y)||l;l(0,100)(100,100)(100,0)(0,0);c.stroke()

उदाहरण का उपयोग: 1 , 2


1
आप बाँध ऑपरेटर के साथ छोटा कर सकते हैं :(l=::c.lineTo)(0,100)(100,100)(100,0)(0,0);c.stroke()
डाउनगोट

@Downgoat धन्यवाद, कौन से ब्राउज़र समर्थन करते हैं? (इसके अलावा, मैंने जो देखा है वह दूसरी कॉल पर त्रुटि करेगा, क्योंकि c.lineToस्वाभाविक रूप से स्वयं वापस नहीं आता है)
ETHproductions

क्योंकि यह एक ES7 सुविधा है
डाउनहिल

3

बाँध संचालक ::

बाइंड ऑपरेटर का इस्तेमाल बार-बार किए जाने वाले कार्यों को कम करने के लिए किया जा सकता है:

(x='abc'.search(a))+x.search(b) // Before
(x=::'abc'.search)(a)+x(b)      // 5 bytes saved

इसके अतिरिक्त यदि आप फ़ंक्शन को किसी भिन्न thisउदाहरण के साथ उपयोग करना चाहते हैं :

s[r='replace'](/a/g,'b')+s[r](/c/g,'d') // Before
(r=s.replace)(/a/g,'b')+s::r(/c/g,'d')  // 1 byte saved

3

बहुत से डेटा संग्रहीत करते समय अल्पविराम से बचना

यदि आपके पास बहुत अधिक डेटा (यानी इंडेक्स, वर्ण, ...) है, जिसे आपको किसी सरणी में संग्रहीत करने की आवश्यकता है, तो आप सभी अल्पविराम को छोड़कर बेहतर हो सकते हैं। यह सबसे अच्छा काम करता है यदि डेटा के हर टुकड़े की लंबाई समान है, 1 स्पष्ट रूप से इष्टतम है।

43 बाइट्स (आधार रेखा)

a=[[3,7,6,1,8,9,4,5,2],[5,4,3,2,7,6,5,4,3]]

34 बाइट्स (कोई अल्पविराम नहीं)

a=[[..."376189452"],[..."543276543"]]

यदि आप अपनी ऐक्सेस एक्सेस को बदलने के इच्छुक हैं , तो आप इसे आगे भी कम कर सकते हैं, उसी तरह मानों को संग्रहीत करना:

27 बाइट्स (एक ही डेटा, केवल ऐक्सेस एक्सेस में बदलाव)

a=[..."376189452543276543"]

केवल अंतिम ब्लॉक ही क्यों हाइलाइट किया गया है?
कैलक्यूलेटरफ़्लीन

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