ECMAScript and এবং তারপরে গল্ফিংয়ের টিপস


88

এটি অন্যান্য "<>> এ গল্ফ করার টিপস" এর অনুরূপ তবে জাভা স্ক্রিপ্টের নতুন বৈশিষ্ট্যগুলিকে নির্দিষ্ট করে ECMAScript 6 এবং এরপরের উপরে আনা হয়েছে।

জাভাস্ক্রিপ্ট মজ্জাগতভাবে একটি খুব বাগাড়ম্বরপূর্ণ ভাষা হল function(){}, .forEach(), এরে, অ্যারেতে অ্যারের মত বস্তু, ইত্যাদি, ইত্যাদি স্ট্রিং রূপান্তর সুপার bloats এবং golfing সুস্থ নয়।

অন্যদিকে, ES6 + এর কয়েকটি সুপার হ্যান্ডি বৈশিষ্ট্য রয়েছে এবং পায়ের ছাপ হ্রাস পেয়েছে। x=>y, [...x]ইত্যাদি ইত্যাদি কয়েকটি উদাহরণ are

দয়া করে কিছু দুর্দান্ত কৌশল পোস্ট করুন যা আপনার কোড থেকে এই কয়েকটি অতিরিক্ত বাইট ছাঁটাই করতে সহায়তা করতে পারে।

দ্রষ্টব্য: ES5 এর কৌশলগুলি জাভাস্ক্রিপ্টে গল্ফ করার জন্য টিপসে ইতিমধ্যে উপলব্ধ ; এই থ্রেডের উত্তরগুলিতে কেবল ES6 এবং অন্যান্য ভবিষ্যতের ES সংস্করণগুলিতে উপলব্ধ কৌশলগুলিতে ফোকাস করা উচিত।

যাইহোক, এই থ্রেড বর্তমানে ব্যবহারকারীদের জন্য যারা ইএস 5 বৈশিষ্ট্যগুলি ব্যবহার করে গল্ফ করে। উত্তরগুলিতে তাদের 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
এখন আমার এখানে ডাউনটা আছে। স্পষ্টতই কেউ এই
টিপটিতে মারাত্মক

দেখতে ঠিক আছে। সেমিকোলনের অভাব কি হতে পারে? ;) (বিটিডাব্লু, আপনি এটিকে বাকি প্যারামিটার হিসাবে ব্যবহার করতে পারেন, যেমন রুবির স্প্ল্যাটস)
gcampbell

আপনি যোগ করতে পারেন যে এটিতে ফাংশন স্বাক্ষরগুলিতে ব্যবহারের মামলা রয়েছে :)
ফেলিক্স ডমব্যাক

মিসিক্লিকের অর্থ ডাউনওয়েট করা নয়
স্ট্যান স্ট্রাম

পছন্দ করুন আমি এই পোস্টে একটি ছোট আপডেট করব যাতে আপনি শেষ পর্যন্ত আপনার ভোট পরিবর্তন করতে পারেন (বা আপনি ইতিমধ্যে করেছিলেন?)
edc65

21

আমি যোগদানের পর থেকে কৌশলগুলি এখানে শিখেছে

আমার প্রাথমিক প্রোগ্রামিংয়ের ভাষা জেএস এবং বেশিরভাগ 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();....

এখানে, আমি অনেক পরিবর্তনশীল আরম্ভ করার জন্য প্রচুর পদ্ধতি কল করছি calling প্রতিটি সূচনা একটি ,বা ব্যবহার করছে ;। এটি আবার লিখিত হতে পারে:

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 বাইট শেভ করতে ব্যবহার করি তা নোট করুন Note

বিবিধ

.search পরিবর্তে .indexOf

উভয়ই একই ফলাফল দেয় তবে searchসংক্ষিপ্ত হয়। যদিও অনুসন্ধান নিয়মিত এক্সপ্রেশন আশা করে, তাই এটি বুদ্ধিমানের সাথে ব্যবহার করুন।

`টেমপ্লেট স্ট্রিংস`

যখন আপনি নির্দিষ্ট শর্তাবলীর উপর ভিত্তি করে এক বা একাধিক স্ট্রিং অংশগুলি সংহত করতে হয় তখন এগুলি খুব কার্যকর hand

জেএসে একটি কুইন আউটপুট দেওয়ার জন্য নিম্নলিখিত উদাহরণটি ধরুন

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

বনাম

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

একটি টেম্পলেট স্ট্রিংয়ে, যা দুটি ব্যাককোটিসের (`) অভ্যন্তরের একটি স্ট্রিং, এ এর ​​অভ্যন্তরীণ যে কোনও কিছুকে ${ }কোড হিসাবে গণ্য করা হয় এবং স্ট্রিংয়ের ফলাফলটি সন্নিবেশ করানোর জন্য মূল্যায়ন করা হয়।

আমি আরও কিছু কৌশল পোস্ট করব। শুভ গল্ফিং!


1
.চর্চা কম হয়, সম্ভব হলে এটি ব্যবহার করুন! তবে এটি .indexOf এর মত নয়। .সার্চ regexpএকটি স্ট্রিং নয়, চায় । চেষ্টা করুন'abc'.search('.')
edc65

@ edc65 আপডেট হয়েছে!
অপ্টিমাইজার

আপনি উদাহরণ পদ্ধতিগুলি সহ মূল অ্যারেটি সংশোধন করতে পারেন। দ্বিতীয়টি হ'ল বর্তমান সূচক এবং তৃতীয়টি অ্যারেটি পুনরাবৃত্তি হচ্ছে।
ইসিয়া মিডোস

8
"এক সপ্তাহ আগে সাইটে যোগদান করেছেন" - 21.4k রেপ ...
গ্যামারকর্পস

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 অনেক খাটো উপায় সরবরাহ করে:

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

আপনি যদি এটি> times বার ব্যবহার করেন তবে এটির parseIntনাম এবং নামটি সংক্ষিপ্ত করা হবে:

(p=parseInt)(v,2)

দীর্ঘ সময়ের pজন্য parseIntআপনাকে অনেকগুলি বাইট সংরক্ষণের জন্য এখন ব্যবহার করা যেতে পারে ।


বেস রূপান্তর ট্রিকটি দুর্দান্ত, তবে এর বেশি সম্ভাবনা রয়েছে যে রূপান্তর সংখ্যাটি আক্ষরিক পরিবর্তে পরিবর্তকের আকারে হয়ে থাকে, এক্ষেত্রে এটি অনেক বেশি দীর্ঘ হয়ে যায়।
অপ্টিমাইজার

1
'0x'+v-0এমনকি সংক্ষিপ্ত, তবে কিছু পরিস্থিতিতে এটি কাজ নাও করতে পারে।
ETH প্রোডাকশনগুলি

1
যাইহোক, 0767(ES5) 0o767স্বীকৃতি (ES6) এর চেয়ে ছোট ।
ক্যামিলো মার্টিন

@ ক্যামিলোমার্টিন 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)
সাইওস

14

অ্যারে সমঝোতা (ফায়ারফক্স 30-57)

দ্রষ্টব্য: অ্যারে বোধগম্যতা কখনই প্রমিত করা হয়নি এবং ফায়ারফক্স 58 দিয়ে অচল করে দেওয়া হয়েছিল। আপনার নিজের বিপদে ব্যবহার করুন।


মূলত, ECMAScript 7 টি বৈশিষ্ট্যে নতুন অ্যারে-ভিত্তিক বৈশিষ্ট্যগুলি রয়েছে contained যদিও এগুলোর বেশিরভাগ চূড়ান্ত সংস্করণ মধ্যে করেননি, ফায়ারফক্স সমর্থন (ইডি) সম্ভবত এই বৈশিষ্ট্যগুলি সবচেয়ে বড়: শৌখিন নতুন বাক্য গঠন যে প্রতিস্থাপন করতে পারেন .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()পরিস্থিতিটির নির্দিষ্টকরণে আসে। এটি উভয় উপায়ে চেষ্টা করা এবং কোনটি আরও কার্যকর হয় তা দেখুন to

পিএস অন্য বোধগম্য সম্পর্কিত টিপ বা এই উত্তরটি উন্নত করার উপায় নির্দ্বিধায় নির্দ্বিধায় মনে করেন!


এখানে রেঞ্জগুলির জন্য একটি কৌশল যা আরও (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]
বোঝাপড়ার

@ এমডব্লিউ 247 আসলে, আমি এখন দেখতে পাচ্ছি যে পরিসীমাগুলি সাধারণত অন্যান্য ভাল ইএস 6 বৈশিষ্ট্যগুলির মতো বোধগম্যতার সাথে কম হয় না। আমি তার পরিবর্তে স্ট্রিংগুলিতে একটি বিভাগ যুক্ত করব এবং আপনাকে রেঞ্জগুলি পরিচালনা করতে দেব।
ETH প্রোডাকশনগুলি

এটি লক্ষণীয় যে অ্যারে সংবিধানগুলি জাভাস্ক্রিপ্টের সমস্ত সাম্প্রতিক সংস্করণ থেকে অবচয় করা হয়েছে এবং সরানো হয়েছে। বিষয়টিতে 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আলাদা (এবং আরও ভাল আইএমও)। দস্তাবেজগুলি দেখুন


2
তবে আপনি যখন গল্ফ-ইনগ হয়, আপনি সাধারণত thisইত্যাদি সম্পর্কে চিন্তা করেন না
অপ্টিমাইজার

1
সাধারণত না, তবে এটি একটি সতর্কতামূলক বিষয়, এটি কখন উঠে আসে তা আপনি কখনই জানেন না। উত্পাদনের এই বাঁধাই ল্যাম্বডাসের জন্য কোনও ফাংশন-স্থানীয় প্রয়োজন না হওয়া আরও সাধারণ।
ইসিয়া মিডোস

এছাড়াও, আপনি যদি আপনার এর সব আর্গুমেন্ট নিতে চান, আপনি "বিশ্রাম" যুক্তি বৈশিষ্ট্য, যেমন ব্যবহার করতে পারেন, f=(...x)=>x যে হবে f(1,2,3) => [1,2,3]
কনার ও'ব্রায়ান

1
এই সাইটের জন্য সুনির্দিষ্ট একটি টিপ এখানে দেওয়া হয়েছে: আপনি যদি এমন কোনও ফাংশনের সাথে জবাব দিচ্ছেন যা ফর্মটি নেয় তবে (x,y)=>...আপনি এটির পরিবর্তে x=>y=>...
কার্টিং

12

evalএকাধিক স্টেটমেন্ট এবং ক সঙ্গে তীর ফাংশন ব্যবহার করেreturn

আরও হাস্যকর কৌশলগুলির মধ্যে একটিতে আমি হোঁচট খেয়েছি ...

একটি সাধারণ তীর ফাংশনটি কল্পনা করুন যার জন্য একাধিক বিবৃতি এবং a 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
আমি মনে করি, কেবল একটি
বেনাম

@ হ্যাঁ, এই দুটি ফাংশনই বেনামে প্রতি 2 বাইট সংরক্ষণ করতে পারে। এক বাইট সঞ্চয় এখনও দাঁড়িয়ে আছে।

1
তবে আরও ভাল: ইওল সর্বশেষ প্রকাশটি প্রকাশিত প্রত্যাবর্তন করে, তাই আপনার প্রয়োজন নেই ;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!):

(১৩ বাইট)

array.join`
`

5
তবে আরও ভাল, আপনি প্রথম বন্ধনী এড়াতে পারেন।
ডকসগুলি

আহ ঠিক. ধন্যবাদ, আমি এটি যোগ করেছি।
চিরু

9

ভর্তি অ্যারে - স্থিতিশীল মান এবং গতিশীল রেঞ্জ

আমি প্রাথমিকভাবে এগুলি বোধগম্যের মতামত হিসাবে রেখেছি, তবে যেহেতু সেই পোস্টটি প্রাথমিকভাবে বোঝার উপর নিবদ্ধ ছিল, তাই আমি অনুভব করেছি যে এটির নিজের জায়গাটি দেওয়া ভাল হবে।

ES6 আমাদের লুপগুলি ব্যবহার না করে স্থিত মান সহ অ্যারে পূরণ করার ক্ষমতা দিয়েছে:

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

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

উভয়ই দৈর্ঘ্যের x এর অ্যারে প্রদান করে, 0 টির মান দিয়ে পূর্ণ।

আপনি যদি গতিশীল মানগুলির সাথে অ্যারেগুলি পূরণ করতে চান (যেমন 0 থেকে x ... 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=>[...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)প্রয়োজনীয় necessary আপনি কি তা ছাড়া চেষ্টা করেছেন?
ETH প্রোডাকশনগুলি

@ এথ প্রডাকশনগুলি আপনি ঠিক বলেছেন, আমি ভুলে গিয়েছিলাম মানচিত্রের পূর্বে 0 পূরণের দরকার নেই। এটি আপনার প্রস্তাবিত চেয়ে 1 অক্ষরকে ছোট করে তোলে, তাই আমি এটি এটি রাখব। ধন্যবাদ!
Mwr247

এছাড়াও, শেষ উদাহরণের জন্য, ঠিক a=>a%2-1কাজ করে a=>a%2<1
ETH প্রোডাকশনগুলি

1
একটি নতুন কৌশল আমি শিখেছি: [...Array(x)]ঠিক পাশাপাশি কাজ করে Array(x).fill()এবং এটি 2 বাইট সংক্ষিপ্ত হয়। x=>[...Array(x)].map((a,i)=>i)
ETH প্রোডাকশনগুলি

1
@ ইউনটানমন খুব সুন্দর! কেবলমাত্র মন্তব্যসমূহ 1 হবে) 1/4উদাহরণটি ছোট লেখা থাকবে [0,0,0,0]এবং 2) স্ট্রিংযুক্ত ফাংশনগুলি বাস্তবায়ন নির্দিষ্ট, সুতরাং কোনও নির্ভরযোগ্য দৈর্ঘ্য ( Mapক্রোমে 32 বাইট নয়, তবে ফায়ারফক্সে 36 বাইট) ফিরিয়ে দেবে না ।
Mwr247

9

তীর ফাংশনে ফিরিয়ে দেওয়া মান Values

এটি সাধারণ জ্ঞান যে কোনও একক বিবৃতি যদি তীর ফাংশন ঘোষণার অনুসরণ করে তবে এটি সেই বিবৃতিটির ফলাফল দেয়:

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

এই শেষ উদাহরণে, আপনারও নিশ্চিত হওয়া দরকার যে সংখ্যাটি সর্বদা পূর্ণসংখ্যার হবে।
ইটিএইচ প্রোডাকশনস

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)শেষেরটির জন্য, উপায়টি খাটো, তবে আপনি ধারণাটি পাবেন।

এখানে ফাংশন যে যদি কাজ riffling একটি দম্পতি আছে 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 এমডিএন সম্পর্কে আরও শিখতে পারেন ।


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

এই উদাহরণে, পুনরাবৃত্তি অবশ্যই অন্য যে কোনও বিকল্পের চেয়ে কম way

চারকোডগুলির যোগফল সম্পর্কে কীভাবে:

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হয় এন , bহয় এন -1 , এবং ফিরে মান a*f(b)

গুরুত্বপূর্ণ নোট: সমস্ত recursive ফাংশন আবশ্যক recursing থামাতে যখন ইনপুট যথেষ্ট ছোট একটি উপায় আছে। ফ্যাক্টরিয়াল ফাংশনে, এটি এর সাথে নিয়ন্ত্রণ করা হয় 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

(প্রোগ্রামগুলি এই উত্তর থেকে নেওয়া )

সংক্ষিপ্ত সমাধানটি কীভাবে সন্ধান করবেন

সাধারণত সবচেয়ে সংক্ষিপ্ত পদ্ধতিটি সন্ধান করার একমাত্র উপায় হ'ল তাদের সকলের চেষ্টা করা। এটা অন্তর্ভুক্ত:

  • loops
  • .map(স্ট্রিংগুলির জন্য, হয় [...s].mapবা s.replaceসংখ্যার জন্য, আপনি একটি পরিসীমা তৈরি করতে পারেন )
  • অ্যারে বোধগম্যতা
  • প্রাক পুনরাবৃত্তি (কখনও কখনও এই বিকল্পগুলির মধ্যে অন্যটি)
  • পোস্ট-পুনরাবৃত্তির

এবং এগুলি কেবল সর্বাধিক সাধারণ সমাধান; সবচেয়ে ভালো সমাধান এই সংমিশ্রণ, অথবা এমনকি হতে পারে কিছু সম্পূর্ণরূপে পৃথক । সংক্ষিপ্ততম সমাধানটি সন্ধান করার সর্বোত্তম উপায় হ'ল সবকিছু চেষ্টা করা


1
এর মানটির জন্য +1, এবং আমি জুটোপিয়ার জন্য আরও একটি +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পতাকা ছাড়াও কোনও রেগেক্স বৈশিষ্ট্য ব্যবহার করতে চাইলে এটি আর সংক্ষিপ্ত হবে না । তবে, আপনি যদি কোনও ভেরিয়েবলের সমস্ত দৃষ্টান্ত প্রতিস্থাপন করেন তবে এটি সাধারণত খুব ছোট:

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

গত কেস, যদি শুধুমাত্র নির্দিষ্ট একটি Regex (যেমন মিলে অক্ষর /\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। পরবর্তী পুনরাবৃত্তিতে কমপক্ষে পরিমাপের পূর্ণসংখ্যার জন্য [0… 2 31 -1] এর সমান পরিমাণে -~kমূলত সমান ।-(-k-1)k+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যা falsy হয়। এটি প্রথম পুনরাবৃত্তির প্রত্যাশিত ফলাফল।

[মূল উত্তরের লিঙ্ক]

উদাহরণ # 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)যখন আপনাকে আর্গুমেন্টগুলির স্কোয়ারের যোগফলের বর্গমূল প্রয়োজন need এটি করতে ইএস 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

@ ইথ প্রডাকশনগুলি আপনার হাইপোটের জন্য আর্গুমেন্ট অ্যারের প্রয়োজন। এবং আপনি কি নিশ্চিত যে ম্যাথ.সাইন-এর জন্য কাজটি -0-র জন্য কাজ করে? (এটি -0 ফিরতে হবে)
ev3 কম্যান্ডার

1
@ ev3commander এগুলি কেবল তাদের নিজ নিজ ES6 সমতুল্যের জন্য লাইন প্রতিস্থাপন হিসাবে বোঝানো হয়েছে, সুতরাং এগুলি 99% ব্যবহারের জন্য ছোট করে দেওয়া হয়। এই ফাংশনগুলি সত্যই পুনরুদ্ধার করার জন্য আরও অনেক বেশি কোডের প্রয়োজন হবে। এছাড়াও, আমি -0 এর জন্য একটি বিশেষ মামলা করার প্রয়োজনের কোনও কারণ দেখতে পাচ্ছি না, কারণ (এএফএইকি) নিজেই এটি নির্দিষ্ট করে ব্যতীত -0 পাওয়ার কোনও উপায় নেই, এবং কোড-গল্ফের মধ্যে এটির ব্যবহারিকভাবে কোনও ব্যবহার নেই। কিন্তু এই জিনিসগুলি নির্দেশ করার জন্য ধন্যবাদ।
ইটিএইচ প্রডাকশনস 23:12 '

5

এর জন্য ছোট ধ্রুবক ব্যাপ্তিকে অনুকূল করা map()

প্রসঙ্গ

map()for[0..N1]

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)N

একটি পরিসীমা জন্য অনুকূলিতকরণ ations[0..N1]

i

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

নোট : কলব্যাক কোডের দৈর্ঘ্য 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

নোট : কলব্যাক কোডের দৈর্ঘ্য F()গণনা করা হয় না।


না করা উচিত 2**26হবে 2**29?
শেগি

@ শেগি হেক ভালো বল ধরা!
আর্নৌলদ

নিজের মধ্যে সম্পাদনা করতে চাইনি কারণ কোড-অন্ধত্ব পেয়েছি! : ডি
শেগি

ব্যবহার করে .keys(), আপনার ল্যাম্বদা লাগবে না:[...Array(10).keys()].map(do_something_with)
দীর্ঘ-লেজুলি

@ লং-লাজুলি যদি আপনার ল্যাম্বডা প্রয়োজন হয় না এবং কেবল একটি পরিসর চান, তবে আপনার সম্ভবত ম্যাপের দরকার নেই ...
আর্নাউল্ড

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

আপনি জানেন যে আপনার একাধিক বিবৃতি এবং একটি রিটার্ন সহ তীর ফাংশনগুলির জন্য ইওল ব্যবহার করা উচিত । কিছু অস্বাভাবিক ক্ষেত্রে আপনি অভ্যন্তরীণ সাব-ফাংশনটি ব্যবহার করে আরও সঞ্চয় করতে পারেন।

আমি অস্বাভাবিক বলি কারণ

  1. প্রত্যাবর্তিত ফলাফল অবশ্যই লুপে বর্ণিত সর্বশেষ প্রকাশ নয়

  2. লুপের আগে অবশ্যই কমপক্ষে 2 টি পৃথক সূচনা থাকতে হবে

এক্ষেত্রে আপনি প্রাথমিক মানগুলির একটিকে প্যারামিটার হিসাবে পাস করে, কোনও রিটার্ন ছাড়াই একটি অভ্যন্তরীণ সাব-ফাংশন ব্যবহার করতে পারেন।

উদাহরণ a থেকে b পর্যন্ত একটি পরিসরের মানগুলির জন্য exp ফাংশনের যোগফলের পারস্পরিক roc

দীর্ঘ পথ - 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 এর প্রারম্ভিককরণগুলিকে একীভূত করতে পারি এবং versionভাল সংস্করণটি আরও কম হয়।


আপনার নমুনায় রাখার দরকার নেই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)

দ্রষ্টব্য : মেটাতে এই পোস্টটি এই সিনট্যাক্সের বৈধতা নিশ্চিত করে।

পুনরাবৃত্তি ফাংশন

কারিকিং সিনট্যাক্স ব্যবহার করা কিছু বাইটস সংরক্ষণ করতে পারে যখন একটি পুনরাবৃত্ত ফাংশন বিভিন্ন যুক্তি গ্রহণ করে তবে কেবল প্রতিটি পুনরাবৃত্তির মধ্যে কিছু আপডেট করতে হবে update

উদাহরণ

নিম্নলিখিত ফাংশনটি পরিসরের সমস্ত পূর্ণসংখ্যার যোগফল গণনা করে [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। এটি সে ক্ষেত্রে সহায়তা করে না তবে এটি আরও যুক্তিযুক্ত ক্ষেত্রে বাইটগুলি সংরক্ষণ করতে পারে।
নিল

হেই, আমি এর জন্য একটি টিপ লেখার কথা ভাবছিলাম :-)
ETH প্রোডাকশনগুলি

4

আদিম-পরীক্ষার ফাংশন

নিম্নলিখিত 28-বাইট ফাংশনটি trueমূল সংখ্যাগুলির falseজন্য এবং অ-প্রাইমগুলির জন্য প্রদান করে:

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

সহজেই অন্যান্য জিনিসগুলি গণনা করার জন্য এটি পরিবর্তন করা যেতে পারে। উদাহরণস্বরূপ, এই 39-বাইট ফাংশনটি সংখ্যার চেয়ে কম বা সমান প্রাইমগুলির সংখ্যা গণনা করে:

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

আপনার যদি ইতিমধ্যে কোনও পরিবর্তনশীল থাকে nযা আপনি প্রাথমিকতার জন্য যাচাই করতে চান, তবে প্রাথমিকতা ফাংশনটি কিছুটা সহজ করা যায়:

(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 এর সাথে কল করা হলে এটি "অত্যধিক পুনরাবৃত্তি" ত্রুটির সাথে ব্যর্থ হবে You আপনি লুপ দিয়ে এটিকে ঘুরে দেখতে পারেন:

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

1
তবে একটি ইনপুট হিসাবে 12345 হিসাবে খুব কম পুনরাবৃত্তি নিয়ে ব্যর্থ হন
edc65

x==1সম্ভবত x<2সঞ্চয় জন্য হতে পারে ।
ক্যালকুলেটরফলাইন

@ ক্যালকুলেটরফালাইন ধন্যবাদ, তবে তারপরে এটি ব্যর্থ হয় 1বা 0(কারণ যথাক্রমে xহবে 0বা হবে -1)
ইটিএইচ প্রোডাকশনস

নির্দিষ্ট ক্ষেত্রে কার্যকর হতে পারে। এছাড়াও, !~-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
আমি লক্ষ করব যে একটি ওআর ব্যবহার _=>_||'asdf'করা বেশিরভাগ ক্ষেত্রেই সংক্ষিপ্ত হয়
ডাউনগোট

@ ডাউনগোট আমি নোট করব যে এটি (খালি স্ট্রিং) এর ইনপুটটির "asdf"জন্য ফিরে আসে ""
ETH প্রোডাকশনগুলি

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 এ গল্ফিং লজিকাল অপারেশনস

"গ্লো (এস 6)"

সাধারণ যুক্তি

বলুন আপনি বিবৃতি নির্মাণ করেছেন 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সত্য / এক্সওআর: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:xx?x:y+3-33+-3
ETH প্রোডাকশনগুলি

@ ইথ প্রডাকশনস আহ, আপনি ঠিক বলেছেন; এটি একটি প্রান্তের কেস। -কাজ করতে পারে, যদি s != t
কনর ও ব্রায়ান

a.filter(t=>t==e).length==a.lengthভুল. এটি হওয়া উচিত!a.filter(t=>t==e).length
ETH প্রোডাকশনগুলি

পছন্দ করুন
কনার ও'ব্রায়েন

3

বার বার ফাংশন কলগুলি সংক্ষিপ্ত করুন

যদি আপনার লং-ইশ নামের কোনও ফাংশনে বারবার কল হয়, যেমন ক্যানভাস ম্যানিপুলেশন:

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

এটি সংক্ষিপ্ত করার traditionalতিহ্যগত উপায়টি হ'ল ফাংশনটির নাম উলেফ করা:

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()
ডাউনগোট

@ ডাউনগোট ধন্যবাদ, কোন ব্রাউজারগুলি এটি সমর্থন করে? (এছাড়াও, আমি যা দেখেছি তা থেকে দ্বিতীয় কলটিতে ত্রুটি ঘটবে, যেহেতু c.lineToপ্রাকৃতিকভাবে নিজেই ফিরে আসে না)
ETH প্রোডাকশনগুলি

আপনার এটি বাবেলটি ঘষতে হবে যেহেতু এটি একটি 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

৪৩ বাইট (বেসলাইন)

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"]

কেন শুধুমাত্র শেষ ব্লক হাইলাইট করা হয়?
ক্যালকুলেটরফলাইন 16

ধন্যবাদ
চিরু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.