Kiat untuk bermain golf dalam JavaScript

133

Apa tips umum yang Anda miliki untuk bermain golf di JavaScript? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk JavaScript (mis. "Hapus komentar" bukan jawaban).

Catatan: Lihat juga Tips untuk Bermain Golf di ECMAScript 6 ke atas

mellamokb
sumber
Saya benar-benar bertanya-tanya, apakah itu diperbolehkan untuk menempatkan variabel di global (menghemat var)? Dan haruskah kode golf JavaScript menjadi fungsi atau mengeluarkan sesuatu secara langsung? Jujur saya pikir ini bisa membuat banyak perbedaan.
pimvdb
1
@ primvdb: Diijinkan, tetapi Anda harus berhati-hati karena dapat menyebabkan efek samping jika suatu fungsi dipanggil beberapa kali dan ia memanipulasi variabel global, atau jika itu adalah fungsi rekursif.
mellamokb

Jawaban:

108

Fancy Untuk Loops

Anda dapat menggunakan standar untuk loop dengan cara yang tidak standar

for ( a; b; c )

pada dasarnya setara dengan:

a;
while ( b )
{
  ...
  c;
}

jadi trik yang bagus adalah menulis kode Anda dengan satu whilelingkaran, dan kemudian membaginya menjadi a,b,cbagian - bagian dalam satu forlingkaran.

Beberapa contoh yang saya tulis :

for(x=y=n;!z;x--,y++)z=i(x)?x:i(y)?y:0
for(a=b=1;b<n;c=a+b,a=b,b=c);

Rantai setter Anda

Jika Anda menginisialisasi atau mengatur ulang beberapa nilai, rangkai nilai ke semua variabel yang membutuhkannya:

a=b=1;

Pengecoran implisit

Jangan periksa tipe Anda, gunakan saja apa adanya. karakter parseInt()biaya 10. Jika Anda perlu membuang string, jadilah kreatif:

a='30';
b='10';
c = a + b; //failure
c = parseInt(a) + parseInt(b) //too long

c = -(-a-b); //try these
c = ~~a+~~b;
c = +a+ +b;
c = a- -b;

Hindari titik koma

JavaScript memiliki penyisipan semi-kolon otomatis. Sering-seringlah menggunakannya.

Satu kalimat

Menghemat kurung dengan mendorong sebanyak mungkin ke dalam satu baris, atau parameter:

a( realParam1, realParam2, fizz='buzz' )

Operator kenaikan / penurunan

a = a - 1;
foo(a);

dan

foo(a);
a = a - 1;

dapat dengan mudah ditulis ulang sebagai

foo(--a);

dan

foo(a--);

masing-masing.

Gunakan thisatau selfalih-alih windowdalam konteks global

Cukup jelas, penghematan 2 karakter.

Gunakan notasi braket untuk akses properti berulang

Ini jelas merupakan tindakan penyeimbangan antara panjang nama properti dan jumlah akses. Alih-alih memanggil a.longFunctionName()dengan notasi titik dua kali, ini lebih pendek untuk menyimpan nama dan memanggil fungsi melalui notasi braket:

a.longFunctionName(b)
a.longFunctionName(c)
//42

-vs-

a[f='longFunctionName'](b)
a[f](c)
//34

ini sangat efektif dengan fungsi seperti document.getElementByIdyang dapat direduksi menjadi d[e].

catatan:

Dengan notasi braket, biaya adalah 6 + name.lengthkarakter yang pertama kali. Setiap akses selanjutnya memiliki biaya 3karakter.

Untuk notasi titik, semua mengakses karakter biaya name.length + 1(+1 untuk .).

Gunakan metode ini jika 6 + name.length + (3 * (accesses - 1)) < accesses * (name.length + 1).

len = panjang nama properti
i = akses minimum untuk memanfaatkan

len | i 
========
1   |  
2   |  
3   | 7 
4   | 4 
5   | 3 
6   | 3 
7   | 3 
8+  | 2 

Jumlah akses juga dapat menjangkau beberapa objek. Jika Anda mengakses .length4 kali atau lebih pada array yang berbeda, Anda dapat menggunakan variabel yang sama dengan memegang string 'length'.

zzzzBov
sumber
5
c = ~~a-~~bseharusnya c = ~~a+~~b. Juga, Anda dapat secara implisit melakukan cast ke integer menggunakan |0, misalnya Math.random()*6|0.
mellamokb
7
Lebih murah untuk memaksa string ke nomor dengan operator plus unary. Jika adan badalah string, Anda dapat melakukannya +a+buntuk mengonversi ke angka dan menambahkannya.
Peter Olson
8
Saya bersumpah akan digunakan d- -bdalam kode saya suatu hari nanti ...
John Dvorak
4
+ a + b tidak bekerja (setidaknya pada milikku ...) // a = "1", b = "1", + a + b // memberikan "11"
imma
2
Untuk "Gunakan Array-Akses untuk panggilan fungsi berulang" jika Anda menggunakan fungsi lebih dari dua kali pada objek yang sama , yang sedikit lebih pendek adalah untuk menetapkan fungsi ke anggota baru sepertia.f=a.longfunctionname;a.f(b);a.f(c);a.f(d)
Martin Ender
131

Memisahkan dengan angka untuk menyimpan tanda kutip:

"alpha,bravo,charlie".split(",") // before
"alpha0bravo0charlie".split(0)   // after
ajax333221
sumber
2
Ini berfungsi, dan saya telah menggunakannya untuk beberapa digit.
Isiah Meadows
12
Lol ini sebenarnya cukup kreatif
NiCk Newman
9
di ES6 ini tidak masalah lagi, Anda bisa melakukannya.split`...`
David Archibald
"alpha,bravo,charlie".split`,`
Kamil Kiełczewski
56

Gunakan operator koma untuk menghindari kawat gigi (juga berlaku untuk C ):

if(i<10)m+=5,n-=3;

Dari pada

if(i<10){m+=5;n-=3}

yang merupakan satu karakter lebih panjang.

mellamokb
sumber
2
Apakah titik koma diperlukan pada akhir sampel pertama?
wjl
4
@wjlafrance: Itu hanya tidak diperlukan jika itu di akhir one-liner.
mellamokb
48

Pembuatan angka acak lebih pendek

Jika Anda membutuhkan boolean acak ( 0atau 1):

new Date&1 // equivalent to Math.random()<0.5

Jika Anda membutuhkan integer acak 0 <= n < 1337:

new Date%1337 // equivalent to Math.floor(Math.random()*1337))

Ini berfungsi karena a Datedisimpan secara internal dalam JavaScript sebagai jumlah milidetik sejak zaman, sehingga new Datesedang dipaksa 123somebignumber456ketika Anda mencoba untuk melakukan bilangan bulat matematika di atasnya.

Tentu saja, angka-angka "acak" ini benar-benar tidak akan acak, terutama jika Anda memanggilnya berkali-kali berturut-turut, jadi ingatlah itu.

Gagang pintu
sumber
1
Hanya ingat jawaban ini ketika membaca Lebih banyak programmer yang salah percaya tentang waktu : “21. Jika Anda membuat dua objek tanggal tepat di samping satu sama lain, mereka akan mewakili waktu yang sama. (generator Heisenbug yang fantastis) ” .
Sebastian Simon
39

Anda dapat menggunakan objek bentuk harafiah dari get / set untuk menghindari penggunaan kata kunci function.

var obj = {
  get f(){
    console.log("just accessing this variable runs this code");
    return "this is actually a function";
  },
  set f(v){
    console.log("you can do whatever you want in here, passed: " + v);
  }
};

1 && obj.f; // runs obj.[[get f]]
obj.f = Infinity; // runs obj.[[set f]](Infinity)

sumber
bagian pengambil / penyetel sangat membantu. thx
gion_13
1
Sebenarnya, yang lebih baik adalah metode objek, jika Anda hanya menggunakannya <= 2 kali. Di sisi lain, fungsi panah jauh lebih baik dalam memotong karakter, karena mereka melayani tujuan yang hampir sama, dan kelas jarang berguna dalam kode golf.
Isiah Meadows
jika dukungan penting, fungsi panah tidak didukung di fx. ie11
Jim Wolff
35

Yang ini kurang dikenal dan kurang digunakan, tetapi bisa mengesankan jika digunakan dalam situasi yang tepat. Pertimbangkan fungsi yang tidak menggunakan argumen dan selalu mengembalikan nomor yang berbeda saat dipanggil, dan nomor yang dikembalikan akan digunakan dalam perhitungan:

var a = [ 
    Math.random()*12|0,
    Math.random()*11|0,
    Math.random()*10|0,
    /* etc... */ 
];

Anda biasanya dapat mempersingkat fungsi ini menggunakan nama variabel satu huruf:

var r=Math.random,a=[r()*12|0,r()*11|0,r()*10|0,r()*9|0,r()*8|0,r()*7|0,r()*6|0,r()*5|0];

Cara yang lebih baik untuk mengurangi panjangnya adalah dengan menyalahgunakan valueOf, yang memberi Anda penghematan 2 karakter per doa. Berguna jika Anda memanggil fungsi lebih dari 5 kali:

var r={valueOf:Math.random},a=[r*12|0,r*11|0,r*10|0,r*9|0r*8|0,r*7|0,r*6|0,r*5|0];
Andy E
sumber
8
Atau, Anda bisa melakukannya seperti ini: let a=[5,6,7,8,9,10,11,12].map(x=>x*Math.random()|0)atau let a=Array(7).map((_,i)=>i*Math.random()|0+5), masing-masing 36 atau 42 byte disimpan.
Isiah Meadows
Apakah mungkin untuk mengganti r(), atau membuatnya lebih pendek?
NiCk Newman
3
r={valueOf:Math.random}Itu hanya genius: D
ETHproduk
1
@Isiah, well ya, Anda bisa melakukannya sekarang :-D
Andy E
32

Memanfaatkan operator hubung singkat

Daripada ifpernyataan panjang atau menggunakan operator ternary, Anda dapat menggunakan &&dan ||untuk mempersingkat kode Anda. Misalnya:

var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);

return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : null;

bisa menjadi

var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);

return match && decodeURIComponent(match[1].replace(/\+/g, ' '));

The ||Operator sering digunakan dalam cara ini untuk pengaturan default:

evt = evt || window.event;

Ini sama dengan menulis

if (!evt)
    evt = window.event;

Membuat string berulang menggunakan Array

Jika Anda ingin menginisialisasi string panjang karakter tertentu, Anda dapat melakukannya dengan membuat array dengan panjang n +1 , di mana n adalah berapa kali Anda ingin mengulangi karakter:

// Create a string with 30 spaces
str = "                              ";

// or
str = Array(31).join(" ");

Semakin besar string, semakin besar penghematannya.

Parsing angka

Gunakan +dan ~operator alih-alih parseFloat()atau parseInt()ketika menyatukan jenis string yang hanya berupa angka ke jenis angka:

var num = "12.6";
parseFloat(num) === +num;  // + is 10 characters shorter than parseFloat()

var num2 = "12"
parseInt(num2) === +num2;   // + is 8 characters shorter than parseInt()

var num3 = "12.6"
parseInt(num3) === ~~num3;  // ~~ is 7 characters shorter than parseInt()

var num4 = "12.6"
parseInt(num4) === num4|0;  // |0 is 7 characters shorter than parseInt()

Namun berhati-hatilah, tipe lain dapat digabungkan dengan operator ini (misalnya, trueakan menjadi 1) string kosong atau string yang hanya berisi ruang putih 0. Namun, ini bisa bermanfaat dalam keadaan tertentu.

Andy E
sumber
6
+1 untuk Membuat string berulang menggunakan Array - tidak memikirkan yang itu.
mellamokb
4
Untuk membuat string berulang, dalam ES6 Anda dapat menggunakanstr.repeat(count)
Oriol
26

Menyelinap inisialisasi variabel ke panggilan prompt () untuk mendapatkan input pengguna

n=prompt(i=5);     // sets i=5 at the same time as getting user input

alih-alih menggunakan

n=prompt();i=5;

Sebagai efek samping, ini menampilkan nilai input di jendela prompt sambil menyimpan 1 karakter.

mellamokb
sumber
12
Ini juga dapat diterapkan ke fungsi apa pun yang tidak menerima argumen.
Casey Chu
3
Bahkan ketika fungsi menerima argumen itu bisa berguna, seperti [1,2,3].join('',i=5)dalam kasus di mana ia menyimpan sepasang kawat gigi.
DocMax
3
@ DocMax: Anda bisa menggunakan operator koma untuk itu - i=5,[1,2,3].join().
Konrad Borowski
@ GlitchMr: Saya bisa, tetapi tidak menyimpan karakter apa pun. Saya setuju bahwa sebagian besar waktu itu akan lebih bersih. Saya pikir mungkin masih ada kasus-kasus di mana pemesanan saya mungkin menghemat char, walaupun saya tidak dapat membuat satu char pada saat ini (dan saya mungkin salah).
DocMax
@DocMax Hanya jika Anda memanfaatkan ASI.
Isiah Meadows
24

Gabungkan sarang untuk loop:

// before:
for(i=5;i--;)for(j=5;j--;)dosomething(i,j)

// after:
for(i=25;i--;)dosomething(0|i/5,i%5)

Contoh dengan nilai yang berbeda untuk i/ j:

// before:
for(i=4;i--;)for(j=7;j--;)dosomething(i,j)

// after:
for(i=28;i--;)dosomething(0|i/7,i%7)
Kae Verens
sumber
(Saya telah mengedit a) kesalahan ketik kecil, tetapi sangat pintar! Perhatikan bahwa ini hanya akan bekerja pada loop bersarang dengan panjang yang sama (kecuali saya salah).
Camilo Martin
1
@ CamiloMartin Tidak, loop tidak harus sama panjangnya. Jumlah iterasi yang dihasilkan adalah i*jdan operator divisi / modulus mengambil nilai individual dari idan j.
quietmint
@ user113215 Anda benar, hebat! :) Saya sudah mengedit jawaban untuk memasukkan contoh.
Camilo Martin
23

Pintasan Unicode

Jika Anda menggunakan banyak properti bawaan di tantangan golf yang besar, Anda dapat menggunakan alias untuk setiap properti dengan satu karakter yang setara:

[Math,Number,S=String,Array].map(b=>
    Object.getOwnPropertyNames(b).map((p,i)=>
        b.prototype[S.fromCharCode(i+248)]=b[p]
    )
)

Setelah mengeksekusi kode di atas, Anda dapat menggunakannya seperti ini:
"foo".Č(/.*/,'bar') // replaces foo with bar

Harganya 118 byte, jadi mungkin tidak berguna dalam situasi tertentu

Mungkin tergantung pada browser dan saya tidak yakin apakah itu lebih pendek dari with(Array){join(foo),...}atau mendefinisikan variabel sebagai properti yang digunakan with(Array){j=join,m=map...}tetapi masih perlu disebutkan.

    Math        Number              String              Array

ø   toSource    prototype           prototype           prototype
ù   abs         NaN                 quote               join
ú   acos        POSITIVE_INFINITY   substring           reverse
û   asin        NEGATIVE_INFINITY   toLowerCase         sort
ü   atan        MAX_VALUE           toUpperCase         push
ý   atan2       MIN_VALUE           charAt              pop
þ   ceil        MAX_SAFE_INTEGER    charCodeAt          shift
ÿ   clz32       MIN_SAFE_INTEGER    contains            unshift
Ā   cos         EPSILON             indexOf             splice
ā   exp         isFinite            lastIndexOf         concat
Ă   floor       isInteger           startsWith          slice
ă   imul        isNaN               endsWith            filter
Ą   fround      toInteger           trim                isArray
ą   log         parseFloat          trimLeft            lastIndexOf
Ć   max         parseInt            trimRight           indexOf
ć   min         length              toLocaleLowerCase   forEach
Ĉ   pow         name                toLocaleUpperCase   map
ĉ   random      arguments           normalize           every
Ċ   round       caller              match               some
ċ   sin                             search              reduce
Č   sqrt                            replace             reduceRight
č   tan                             split   
Ď   log10                           substr  
ď   log2                            concat  
Đ   log1p                           slice   
đ   expm1                           fromCharCode    
Ē   cosh                            fromCodePoint   
ē   sinh                            localeCompare   
Ĕ   tanh                            length  
ĕ   acosh                           name    
Ė   asinh                           arguments   
ė   atanh                           caller  
Ę   hypot           
ę   trunc           
Ě   sign            
ě   cbrt            
Ĝ   E           
ĝ   LOG2E           
Ğ   LOG10E          
ğ   LN2         
Ġ   LN10            
ġ   PI          
Ģ   SQRT2           
ģ   SQRT1_2         
bebe
sumber
Saya menggunakan google chrome, dan ini semua tidak terdefinisi.
SuperJedi224
Pasti sangat spesifik dengan firefox. Maaf untuk ketidaknyamanannya.
bebe
Mengapa semua ini karakter khusus? Mengapa tidak menggunakan ASCII yang dapat dicetak? (lebih mudah untuk mengetik, lebih dapat diandalkan, dan hanya 1 byte untuk bermain golf)
Cyoce
Ini tidak benar-benar berhasil Mathkarena tidak memiliki .prototypeatribut. MathNamun, menghapus , saya berhasil memasukkan potongan ini ke potongan 114 byte yang menetapkan semuanya ke huruf byte tunggal. Anda dapat menemukannya di sini .
ETHproduk
1
Anda juga dapat memasukkan solusi saya ke 106 byte dengan biaya memindahkan semua properti ini ke kisaran À- ÿ, yang masing-masing masih 1 byte dalam pengkodean ISO-8859-1 (yang didukung JS). Di Firefox 50, sayangnya ini menempatkan .localeComparemetode ×, tapi itu seharusnya tidak menjadi masalah. source
ETHproductions
22

Mengonversi satu whilelingkaran menjadi satu forlingkaran sering kali setara:

while(i--);
for(;i--;);

Tetapi bentuk kedua dapat menggabungkan inisialisasi variabel:

i=10;while(i--);
for(i=10;i--;);

Perhatikan bentuk kedua adalah satu karakter lebih pendek dari bentuk pertama.

mellamokb
sumber
6
Atau, lebih baik lagi, gunakan saja untuk loop. Benar-benar tidak ada kasus di mana menggunakan for loop menghasilkan kode yang lebih besar, sejauh yang saya alami.
Isiah Meadows
22

Penyalahgunaan pengecualian

dalam kasus string / karakter literal dilarang, Anda dapat menggunakan blok coba tangkap:

try{something0}catch(e){str=e.message.split(0)[0]}

sekarang strsama dengan"something"

jika diperlukan lebih banyak string, Anda dapat mengaitkannya dengan angka (mis. nol)

try{something0foo0bar0}catch(e){arr=e.message.split(0)}

sekarang arrsama dengan["something", "foo", "bar", " is not defined"]

bebe
sumber
18

Jika Anda menginisialisasi variabel ke 1dalam setiap iterasi loop (misalnya, mengatur ulang variabel dalam loop luar untuk loop dalam), seperti berikut (dari jawaban saya untuk pertanyaan ini ):

for(j=n-2;p=1,j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;
          ^^^^

Karena hasil dari kondisi seperti j++<=nadalah 1kapanpun itu benar, Anda bisa menetapkan kondisi langsung ke variabel (karena ketika itu menjadi salah, loop akan berhenti dieksekusi dan tidak lagi penting):

for(j=n-2;p=j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;
          ^^^^^^^^

Anda biasanya dapat menyimpan 2 karakter menggunakan metode ini. Salam @ugorenatas ide dalam komentar untuk jawaban itu.


Sebagai contoh lain, saya juga menerapkan trik ini untuk jawaban saya di sini dengan ekspresi w=r=++c<S.lengthdi luar saya untuk loop, menyimpan total 4 karakter.

mellamokb
sumber
18

Jika Anda dapat menerima skrip khusus Spidermonkey (untuk saat ini), Anda dapat menggunakan fungsi panah ECMAScript 6 . Memulai penulisan kode seperti berikut ini.

a.map(function(x){return x*2}) // function? return?

Anda dapat mempersingkat seperti ini.

a.map(x=>x*2)
Konrad Borowski
sumber
17

Jika Anda perlu memeriksa NaN, jangan gunakan isNaN(x), tetapi gunakan x!=x, yang lebih pendek dan juga berfungsi.

if(isNaN(x)){
if(x!=x){

Perhatikan bahwa ini hanya berfungsi jika typeof(x) === "number"; jika string misalnya, isNaN("string")kembali true, tetapi "string" != "string"kembali false. Terima kasih kepada Cyoce karena menunjukkan ini!

ProgramFOX
sumber
2
Itu penggunaan jenius dari kekhasan ini. +1
ETHproduksi
Peringatan: ini tidak selalu setara: isNaN("string")pengembalian true, sedangkan "string"!="string"pengembalian false(jelas)
Cyoce
@Cyoce Poin bagus, terima kasih! Saya mengedit jawaban saya.
ProgramFOX
Dalam banyak kasus, Anda bahkan dapat menggunakan if(!x){, jika Anda mendeteksi NaNsecara eksplisit.
Hohmannfan
1
Casting xke angka,, +x!=+xmembuatnya setara dengan isNaN(x), namun masih 2 karakter lebih pendek. Kemudian, +"string"!=+"string"mengembalikan true.
Tomas Langkaas
15

Jumlah array / produk / hasil bagi

ES5 : 17 byte

eval(a.join('+'))

ES6 : 15 byte

eval(a.join`+`)

Tentu saja Anda dapat menukar dengan +apa pun yang Anda inginkan, misalnya, *untuk produk atau /bagi hasil.

George Reith
sumber
14

Gunakan operasi bitwise untuk membulatkan angka ke nol:

// do this
T=Math.random()*6+1|0

// or do this
T=~~(Math.random()*6+1)

(Sumber: Tip dadu acak )

Diutamakan operator menentukan mana yang akan lebih pendek dalam program Anda.

Tolong berdiri
sumber
2
Ini juga dapat digunakan untuk menyatukan input string menjadi integer, yaitu n=prompt()|0,.
mellamokb
1
bitwise juga sangat cepat dibandingkan dengan math.floor: jsperf.com/floor-vs-bitwise
vsync
@vsync: Aneh. Saya mendapatkan math.floor sekitar dua kali lebih cepat dari bitwise di Chrome 11.0.696.77.
mellamokb
sangat aneh. bagi saya keduanya kecepatan kurang lebih sama & super cepat di Chrome, tetapi dalam FF bitwise jauh lebih cepat daripada Chrome, danMath.floor sangat lambat..hampir tidak boleh digunakan saya akan mengatakan.
vsync
Agar komentar tetap mutakhir, dalam Fx saat ini, keduanya cepat & hampir sama. Bukan berarti itu akan menjadi hambatan di tempat pertama, dibandingkan dengan kode sekitarnya ...
FireFly
14

Tip Looping I

Anda dapat menyimpan 1karakter saat mengulang dengan mengubah ipada saat terakhir kali digunakan:

//not so god
for(i=0;i<3;i++){
  alert(i);
}

//best
for(i=0;i<3;){
  alert(i++);
}

Catatan: bekerja dengan --terlalu (tapi modifikasi loop sesuai untuk menghindari perulangan tak terbatas)


Tip Looping II

Ada beberapa skenario di mana Anda dapat menyimpan satu karakter dengan bermain dengan operator dan nilai yang meningkat:

for(i=0;i++<9;)
for(i=0;++i<10;)

Catatan: Anda harus memperhatikan kapan misalnya 0 to -1. dan 9 to 10, 99 to 100, jadi main-main sampai Anda menemukan cara untuk menyelamatkan karakter

ajax333221
sumber
13

Gunakan ^sebagai ganti!= atau ==ketika membandingkan ke integer

//x!=3?a:b
  x^3?a:b

//x==3?a:b
  x^3?b:a

Ganti panggilan ke fungsi Matematika bawaan dengan ekspresi lebih pendek

//Math.ceil(n)
  n%1?-~n:n

//Math.floor(n)
  ~~n
  0|n

//Math.abs(n)
  n<0?-n:n

//Math.round(n)
  n+.5|0

//Math.min(x,y)
  x<y?x:y

//Math.max(x,y)
  y<x?x:y
Tomas Langkaas
sumber
2
Atau, Anda bisa menggunakan -bukan !=bilangan bulat; Misalnya, n!=1?a:bakan setara dengann-1?a:b
vrugtehagel
10

Yang perlu diperhatikan adalah bahwa Anda dapat menggunakan string sebagai ganti nol dalam beberapa kasus untuk menyimpan beberapa byte di sana-sini dalam loop:

s='';for(i=0;i++<9;)s+=i
for(i=s='';i++<9;)s+=i
// s="123456789", i=10
Dom Hastings
sumber
1
Saya mencoba "+ + + di konsol sebelumnya bertanya-tanya apakah itu akan berhasil, tentu saja harus dalam variabel terlebih dahulu. Terima kasih!
Vartan
10

Sangat sederhana, meski begitu, tidak ada yang menyebutkannya.

Jika Anda menggunakan Math.min()atau Math.max()Anda dapat menyimpan 6 karakter dengan melakukan ini:

Math.min(a,b)  // 13 chars
a<b?a:b        //  7 chars

Math.max(a,b)
a>b?a:b
António Almeida
sumber
10

Pembulatan

Saya tahu bahwa alternatif Math.floor()telah diposting, tetapi bagaimana dengan yang lain?

Lantai:

Math.floor(x) //before
0|x           //after

Pembulatan:

Math.round(x) //before
0|x+.5        //after

Plafon:

Math.ceil(x) //before
x%1?-~x:x    //after - credits to @Tomas Langkaas
Mama Fun Roll
sumber
1
Perhatikan bahwa 0|x+1cukup tambahkan 1 jika angka yang ingin Anda temukan langit-langit sudah bilangan bulat Alternatif yang aman (kebanyakan) adalah 0|x+1-1e9, tetapi ini hanya tiga byte lebih pendek.
ETHproduksi
@ ETHproductions bukan maksud Anda 0|x+1-1e-9?
Mama Fun Roll
Ups, ya. Terima kasih telah menunjukkannya. (Untuk beberapa alasan, saya tidak bisa melakukan @ (nama pengguna Anda) ...)
ETHproduksi
Mungkin karena karakter nama pengguna saya terbalik :)
Mama Fun Roll
1
Untuk plafon, x%1?-~x:x(9 karakter) adalah alternatif yang lebih baik. Namun, seperti alternatif lantai 0|xdan ~~x, itu hanya berfungsi untuk angka positif.
Tomas Langkaas
9

Dalam kasus di mana Anda menggunakan operator ternary untuk memilih antara dua angka , dan syaratnya adalah boolean atau angka 1 or 0 , Anda bisa melakukan operasi matematika sebagai gantinya:

(x ? num1 : num2) conclusions:

    1)if num1 equals num2, there ARE savings
    2)if num1 is (+1) or (-1) than num2, there ARE savings
    3)if either num1 or num2 equals to 0, there ARE savings
    4)it is MORE LIKELY to find greater savings on num1>num2 instead of num1<num2
    5)in method (*A) and (*B), savings are NOT GUARANTEED

    a)num1>num2
        i)(num1==(num2+1))
            ex1: (x?5:4) to (x+4)
            ex2: (x?8:7) to (x+7)
        ii)num2==0
            ex1: (x?3:0) to (x*3)
            ex2: (x?7:0) to (x*7)
        iii)
            (*A) or (*B) //one might be shorter

    b)num1<num2
        i)((num1+1)==num2)
            ex1: (x?4:5) to (5-x)
            ex2: (x?7:8) to (8-x)
        ii)num1==0
            ex1: (x?0:3) to (!x*3)
            ex2: (x?0:7) to (!x*7)
        iii)
            (*A) or (*B) //one might be shorter

    c)num1==num2
        i)
            ex1: (x?5:5) to (5)
            ex2: (x?-3:-3) to (-3)

    (*A) use ((x*(num1-num2))+num2)
        ex1: (x?8:4)   to ((x*4)+4)
        ex2: (x?4:8)   to ((x*-4)+8)

        ex3: (x?6:-4)  to ((x*10)-4)
        ex4: (x?-4:6)  to ((x*-10)+6)

        ex5: (x?4:-6)  to ((x*10)-6)
        ex6: (x?-6:4)  to ((x*-10)+4)

        ex7: (x?-5:-9) to ((x*4)-9)
        ex8: (x?-9:-5) to ((x*-4)-5)

    (*B) use ((!x*(num2-num1))+num1)
        ex1: (x?8:4)   to ((!x*-4)+8)
        ex2: (x?4:8)   to ((!x*4)+4)

        ex3: (x?6:-4)  to ((!x*-10)+6)
        ex4: (x?-4:6)  to ((!x*10)-4))

        ex5: (x?4:-6)  to ((!x*-10)+4)
        ex6: (x?-6:4)  to ((!x*10)-6)

        ex7: (x?-5:-9) to ((!x*-4)-5)
        ex8: (x?-9:-5) to ((!x*4)-9)

Catatan: Selain ini, Anda akan perlu untuk menghapus yang tidak perlu 0-, +0, +-dll

Note2: ada kasus yang terisolasi di mana (x) !== (x?1:0), sebagaimana xmestinya typeof === "number"untuk itu untuk bekerja. Namun, dalam kasus (-x)ini berfungsi dengan baik.

Note3: Jika Anda tidak menemukan tabungan, cukup gunakan yang pertama(x?y:z)

Sebelumnya saya pikir metode B tidak pernah bisa mengalahkan A, namun ada pengecualian:

(x?97:100) //original

(-3*x+100)
(3*!x+97)

Saya membuat proyek github yang membuat penyederhanaan bagi kami ( jsFiddle demo )

mellamokb
sumber
@ ajax333221 void 0(ini bukan fungsi, tapi kata kunci) bukan nilai, hanya mengembalikan undefined.
Camilo Martin
@CamiloMartin Anda benar, saya juga sekarang mengerti maksud dari jawaban ini, namun aharus 1 atau 0 agar bisa berfungsi
ajax333221
@ ajax333221 Ya, sebenarnya lucunya tentang kode golf kepada saya adalah bahwa sebagian besar trik terbaik hanya bekerja untuk hal tertentu yang Anda lakukan, dan orang merasa sangat pintar untuk menemukan salah satu kasing ini dengan solusi pojok: D Oleh cara, Anda tidak perlu menghapus komentar ...
Camilo Martin
9

tl; dr: Gunakan fitur ES6!

Fungsi panah

Doc: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/arrow_functions
Contoh:

s = x => x*x
// s = function (x) {
//   return x * x;
// }
Florent
sumber
Fungsi panah sudah disebutkan pada 13 Oktober 13 di 15:42 . Tapi itu for.. ofitu keren. Bahkan lebih pendek dari for each.. in.
manatwork
2
Sintaks pemahaman array tampaknya salah. Menurut dokumentasi harus seperti di Python: b = [s(x) for (x of a)].
manatwork
@manatwork Sampel di atas berjalan baik di REPL Traceur
Florent
Tidak tahu tentang Traceur, tetapi Anda menyebutkan ECMAScript dan menunjuk ke dokumentasi Mozilla. Dan pemahaman array tidak satupun dari mereka sepertinya Anda yang menulisnya.
manatwork
1
Pemahaman array sebenarnya ditarik di tengah jalan.
Isiah Meadows
9

Pelecehan literal

Sampel terbaru: Periksa apakah "c"huruf besar atau kecil, tidak masalah jika bukan huruf

"c"<{} // returns false, lower case
"C"<{} // returns true, upper case
l4m2
sumber
3
Bagaimana cara kerjanya?
Sapi dukun
2
@Cowsquack String({})memberi "[object Object]".
Dennis
8

Cara membandingkan angka dengan bantuan bagaimana angka berubah menjadi boolean:

Jika Anda akan memeriksa apakah ada sesuatu yang sama dengan angka positif , Anda dapat mengurangi jumlah itu dan membalikkan apa yang ada di dalam ifdan elsememblokir:

//simplified examples:
x==3?"y":"n"; <- 13 Chars
x-3?"n":"y"; <- 12 Chars

//expanded examples:
if(x==3){
    yes();
}else{
    no();
}

if(x-3){
    no();
}else{
    yes();
}

Dan jika Anda ingin membandingkan dengan angka negatif (* berbeda dari -1), Anda hanya perlu menambahkan nomor ini daripada mengurangi.

* baik, Anda pasti bisa menggunakan x.indexOf(y) + 1, tetapi dalam kasus khusus -1Anda memiliki kesempatan untuk menggunakannya ~x.indexOf(y).

ajax333221
sumber
8

Gunakan fitur "penutupan penutupan" Mozilla yang tidak standar untuk menyimpan banyak karakter dalam skrip yang hanya perlu bekerja di mesin SpiderMonkey / Firefox atau Rhino. Sebagai contoh,

function foo(){return bar}

menjadi

function foo()bar

Lihat halaman Stack Overflow untuk mengetahui trik lainnya.

Tolong berdiri
sumber
2
Itu bukan Javascript. Itu STASIUN SPACE !!!
Thomas Eding
1
ECMAScript 6 untuk menyelamatkan! ->bar
Ry-
5
ECMAScript 6:, let foo = () => bar;ironisnya lebih pendek dari kode golf di atas.
Isiah Meadows
1
ECMAScript 6:, foo=_=>barbahkan lebih pendek.
ETHproduksi
tautan itu rusak.
Cyoce
8

Alih-alih menulis trueAnda bisa menggunakan !0.

Wolle Vanillebär Lutz
sumber
4
Demikian juga !1untuk false.
James M. Lay
10
Lebih baik lagi, gunakan 1untuk truedan 0untuk false, kecuali Anda benar-benar membutuhkan nilai literal.
ETHproductions
8

Mengubah ke Boolean :

if(b){b=true}else{b=false}
b=b?true:false;
b=b?!0:!1;
b=!!b;

Catatan: ini berubah 0, "", false, null, undefineddan NaNuntuk false(segala sesuatu yang lain untuk true)

ajax333221
sumber