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
code-golf
tips
javascript
mellamokb
sumber
sumber
var
)? Dan haruskah kode golf JavaScript menjadi fungsi atau mengeluarkan sesuatu secara langsung? Jujur saya pikir ini bisa membuat banyak perbedaan.Jawaban:
Fancy Untuk Loops
Anda dapat menggunakan standar untuk loop dengan cara yang tidak standar
pada dasarnya setara dengan:
jadi trik yang bagus adalah menulis kode Anda dengan satu
while
lingkaran, dan kemudian membaginya menjadia,b,c
bagian - bagian dalam satufor
lingkaran.Beberapa contoh yang saya tulis :
Rantai setter Anda
Jika Anda menginisialisasi atau mengatur ulang beberapa nilai, rangkai nilai ke semua variabel yang membutuhkannya:
Pengecoran implisit
Jangan periksa tipe Anda, gunakan saja apa adanya. karakter
parseInt()
biaya10
. Jika Anda perlu membuang string, jadilah kreatif: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:
Operator kenaikan / penurunan
dan
dapat dengan mudah ditulis ulang sebagai
dan
masing-masing.
Gunakan
this
atauself
alih-alihwindow
dalam konteks globalCukup 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:-vs-
ini sangat efektif dengan fungsi seperti
document.getElementById
yang dapat direduksi menjadid[e]
.catatan:
Dengan notasi braket, biaya adalah
6 + name.length
karakter yang pertama kali. Setiap akses selanjutnya memiliki biaya3
karakter.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
Jumlah akses juga dapat menjangkau beberapa objek. Jika Anda mengakses
.length
4 kali atau lebih pada array yang berbeda, Anda dapat menggunakan variabel yang sama dengan memegang string'length'
.sumber
c = ~~a-~~b
seharusnyac = ~~a+~~b
. Juga, Anda dapat secara implisit melakukan cast ke integer menggunakan|0
, misalnyaMath.random()*6|0
.a
danb
adalah string, Anda dapat melakukannya+a+b
untuk mengonversi ke angka dan menambahkannya.d- -b
dalam kode saya suatu hari nanti ...a.f=a.longfunctionname;a.f(b);a.f(c);a.f(d)
Memisahkan dengan angka untuk menyimpan tanda kutip:
sumber
.split`...`
"alpha,bravo,charlie".split`,`
Gunakan operator koma untuk menghindari kawat gigi (juga berlaku untuk C ):
Dari pada
yang merupakan satu karakter lebih panjang.
sumber
Pembuatan angka acak lebih pendek
Jika Anda membutuhkan boolean acak (
0
atau1
):Jika Anda membutuhkan integer acak
0 <= n < 1337
:Ini berfungsi karena a
Date
disimpan secara internal dalam JavaScript sebagai jumlah milidetik sejak zaman, sehingganew Date
sedang dipaksa123somebignumber456
ketika 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.
sumber
Anda dapat menggunakan objek bentuk harafiah dari get / set untuk menghindari penggunaan kata kunci
function
.sumber
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:
Anda biasanya dapat mempersingkat fungsi ini menggunakan nama variabel satu huruf:
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:sumber
let a=[5,6,7,8,9,10,11,12].map(x=>x*Math.random()|0)
ataulet a=Array(7).map((_,i)=>i*Math.random()|0+5)
, masing-masing 36 atau 42 byte disimpan.r()
, atau membuatnya lebih pendek?r={valueOf:Math.random}
Itu hanya genius: DMemanfaatkan operator hubung singkat
Daripada
if
pernyataan panjang atau menggunakan operator ternary, Anda dapat menggunakan&&
dan||
untuk mempersingkat kode Anda. Misalnya:bisa menjadi
The
||
Operator sering digunakan dalam cara ini untuk pengaturan default:Ini sama dengan menulis
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:
Semakin besar string, semakin besar penghematannya.
Parsing angka
Gunakan
+
dan~
operator alih-alihparseFloat()
atauparseInt()
ketika menyatukan jenis string yang hanya berupa angka ke jenis angka:Namun berhati-hatilah, tipe lain dapat digabungkan dengan operator ini (misalnya,
true
akan menjadi1
) string kosong atau string yang hanya berisi ruang putih0
. Namun, ini bisa bermanfaat dalam keadaan tertentu.sumber
str.repeat(count)
Menyelinap inisialisasi variabel ke panggilan prompt () untuk mendapatkan input pengguna
alih-alih menggunakan
Sebagai efek samping, ini menampilkan nilai input di jendela prompt sambil menyimpan 1 karakter.
sumber
[1,2,3].join('',i=5)
dalam kasus di mana ia menyimpan sepasang kawat gigi.i=5,[1,2,3].join()
.Gabungkan sarang untuk loop:
Contoh dengan nilai yang berbeda untuk
i
/j
:sumber
i*j
dan operator divisi / modulus mengambil nilai individual darii
danj
.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:
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 digunakanwith(Array){j=join,m=map...}
tetapi masih perlu disebutkan.sumber
Math
karena tidak memiliki.prototype
atribut.Math
Namun, menghapus , saya berhasil memasukkan potongan ini ke potongan 114 byte yang menetapkan semuanya ke huruf byte tunggal. Anda dapat menemukannya di sini .À
-ÿ
, yang masing-masing masih 1 byte dalam pengkodean ISO-8859-1 (yang didukung JS). Di Firefox 50, sayangnya ini menempatkan.localeCompare
metode×
, tapi itu seharusnya tidak menjadi masalah. sourceMengonversi satu
while
lingkaran menjadi satufor
lingkaran sering kali setara:Tetapi bentuk kedua dapat menggabungkan inisialisasi variabel:
Perhatikan bentuk kedua adalah satu karakter lebih pendek dari bentuk pertama.
sumber
Penyalahgunaan pengecualian
dalam kasus string / karakter literal dilarang, Anda dapat menggunakan blok coba tangkap:
sekarang
str
sama dengan"something"
jika diperlukan lebih banyak string, Anda dapat mengaitkannya dengan angka (mis. nol)
sekarang
arr
sama dengan["something", "foo", "bar", " is not defined"]
sumber
Jika Anda menginisialisasi variabel ke
1
dalam setiap iterasi loop (misalnya, mengatur ulang variabel dalam loop luar untuk loop dalam), seperti berikut (dari jawaban saya untuk pertanyaan ini ):Karena hasil dari kondisi seperti
j++<=n
adalah1
kapanpun itu benar, Anda bisa menetapkan kondisi langsung ke variabel (karena ketika itu menjadi salah, loop akan berhenti dieksekusi dan tidak lagi penting):Anda biasanya dapat menyimpan 2 karakter menggunakan metode ini. Salam
@ugoren
atas 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.length
di luar saya untuk loop, menyimpan total 4 karakter.sumber
Jika Anda dapat menerima skrip khusus Spidermonkey (untuk saat ini), Anda dapat menggunakan fungsi panah ECMAScript 6 . Memulai penulisan kode seperti berikut ini.
Anda dapat mempersingkat seperti ini.
sumber
Jika Anda perlu memeriksa NaN, jangan gunakan
isNaN(x)
, tetapi gunakanx!=x
, yang lebih pendek dan juga berfungsi.Perhatikan bahwa ini hanya berfungsi jika
typeof(x) === "number"
; jika string misalnya,isNaN("string")
kembalitrue
, tetapi"string" != "string"
kembalifalse
. Terima kasih kepada Cyoce karena menunjukkan ini!sumber
isNaN("string")
pengembaliantrue
, sedangkan"string"!="string"
pengembalianfalse
(jelas)if(!x){
, jika Anda mendeteksiNaN
secara eksplisit.x
ke angka,,+x!=+x
membuatnya setara denganisNaN(x)
, namun masih 2 karakter lebih pendek. Kemudian,+"string"!=+"string"
mengembalikan true.Jumlah array / produk / hasil bagi
ES5 : 17 byte
ES6 : 15 byte
Tentu saja Anda dapat menukar dengan
+
apa pun yang Anda inginkan, misalnya,*
untuk produk atau/
bagi hasil.sumber
Gunakan operasi bitwise untuk membulatkan angka ke nol:
(Sumber: Tip dadu acak )
Diutamakan operator menentukan mana yang akan lebih pendek dalam program Anda.
sumber
n=prompt()|0
,.Math.floor
sangat lambat..hampir tidak boleh digunakan saya akan mengatakan.Tip Looping I
Anda dapat menyimpan
1
karakter saat mengulang dengan mengubahi
pada saat terakhir kali digunakan: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:
Catatan: Anda harus memperhatikan kapan misalnya
0 to -1
. dan9 to 10, 99 to 100
, jadi main-main sampai Anda menemukan cara untuk menyelamatkan karaktersumber
Gunakan
^
sebagai ganti!=
atau==
ketika membandingkan ke integerGanti panggilan ke fungsi Matematika bawaan dengan ekspresi lebih pendek
sumber
-
bukan!=
bilangan bulat; Misalnya,n!=1?a:b
akan setara dengann-1?a:b
Yang perlu diperhatikan adalah bahwa Anda dapat menggunakan string sebagai ganti nol dalam beberapa kasus untuk menyimpan beberapa byte di sana-sini dalam loop:
sumber
Sangat sederhana, meski begitu, tidak ada yang menyebutkannya.
Jika Anda menggunakan
Math.min()
atauMath.max()
Anda dapat menyimpan 6 karakter dengan melakukan ini:sumber
Pembulatan
Saya tahu bahwa alternatif
Math.floor()
telah diposting, tetapi bagaimana dengan yang lain?Lantai:
Pembulatan:
Plafon:
sumber
0|x+1
cukup tambahkan 1 jika angka yang ingin Anda temukan langit-langit sudah bilangan bulat Alternatif yang aman (kebanyakan) adalah0|x+1-1e9
, tetapi ini hanya tiga byte lebih pendek.0|x+1-1e-9
?x%1?-~x:x
(9 karakter) adalah alternatif yang lebih baik. Namun, seperti alternatif lantai0|x
dan~~x
, itu hanya berfungsi untuk angka positif.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:Catatan: Selain ini, Anda akan perlu untuk menghapus yang tidak perlu
0-
,+0
,+-
dllNote2: ada kasus yang terisolasi di mana
(x) !== (x?1:0)
, sebagaimanax
mestinyatypeof === "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:
Saya membuat proyek github yang membuat penyederhanaan bagi kami ( jsFiddle demo )
sumber
void 0
(ini bukan fungsi, tapi kata kunci) bukan nilai, hanya mengembalikanundefined
.a
harus 1 atau 0 agar bisa berfungsitl; dr: Gunakan fitur ES6!
Fungsi panah
Doc: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/arrow_functions
Contoh:
sumber
for
..of
itu keren. Bahkan lebih pendek darifor each
..in
.b = [s(x) for (x of a)]
.Pelecehan literal
Sampel terbaru: Periksa apakah
"c"
huruf besar atau kecil, tidak masalah jika bukan hurufsumber
String({})
memberi"[object Object]"
.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
if
danelse
memblokir: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-1
Anda memiliki kesempatan untuk menggunakannya~x.indexOf(y)
.sumber
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,
menjadi
Lihat halaman Stack Overflow untuk mengetahui trik lainnya.
sumber
->bar
let foo = () => bar;
ironisnya lebih pendek dari kode golf di atas.foo=_=>bar
bahkan lebih pendek.Gunakan
if(~a.indexOf(b))
sebagai gantiif(a.indexOf(b)!=-1)
sumber
Alih-alih menulis
true
Anda bisa menggunakan!0
.sumber
!1
untukfalse
.1
untuktrue
dan0
untukfalse
, kecuali Anda benar-benar membutuhkan nilai literal.Mengubah ke Boolean :
Catatan: ini berubah
0
,""
,false
,null
,undefined
danNaN
untukfalse
(segala sesuatu yang lain untuktrue
)sumber