Generowanie alfabetu w JavaScript

21

Jestem prawie pewien, że nie ma lepszego sposobu na zrobienie tego, ale pomyślałem, że nie zaszkodzi zapytać.

Mam dość pisania a='abcdefghijklmnopqrstuvwxyz'.

Fajne języki mają Range('a'..'z')lub podobne

Co możemy zrobić z JS tak krótkim, jak to możliwe?

for(i=97,a='';i<123;){a+=String.fromCharCode(i++)}

jest dłuższy niż tylko alfabet - ale gwarantuje, że gdzieś nie spieprzę.

Mam nadzieję, że istnieje nieprzyjemnie zmienny sposób na uzyskanie az w mniej niż 50 postaciach.

Pomyślałem z i=97;Array(26).map(x=>String.fromChar....i++

ale zanim dołączyłem, zawsze było o wiele dłużej, a potem podzieliłem tablicę (26), aby była użyteczna


Edycja: udało mi się

[...Array(26)].reduce(a=>a+String.fromCharCode(i++),'',i=97)

60 bajtów

Charlie Wynn
źródło
11
@muddyfish, LuisMendo: To jest temat na meta.
Klamka
1
[...Array(26)].map((q,w)=>String.fromCharCode(w+97))ma 52 bajty i dodaj kolejne 7 dla.join``
andlrc
Powiązane: stackoverflow.com/questions/3895478/…
Cyfrowa trauma
@ dev-null a = ''; i = 97; [... Array (26)]. map (b => a + = String.fromCharCode (i ++)) ma 60, ale dba o dołączenie jak sobie radzisz w 7 bez uzyskania przecinków w wyniku?
Charlie Wynn,
1
@CharlieWynn[...Array(26)].map((q,w)=>String.fromCharCode(w+97)).join``
andlrc

Odpowiedzi:

12

Alternatywa dla String.fromCharCode

... jeśli jesteś zadowolony z samego alfabetu.

for(i=9,a='';++i<36;)a+=i.toString(36) // 38, cannot be used in an expression
[...Array(26)].map(_=>(++i).toString(36),i=9).join`` // 52 directly returnig the string desired
[...Array(26)].map(_=>a+=(++i).toString(36),a='',i=9) // 53 assign to a variable
(i=9,[for(_ of Array(26))(++i).toString(36)].join``) // 52 ES7 direct return
i=9,a='',[for(_ of Array(26))a+=(++i).toString(36)] // 51 ES7 assign to a variable
edc65
źródło
1
O cholera, to sprytne. Czyli zaczyna się od 10, konwertuje do bazy 36 i drukuje? więc az!
Charlie Wynn
Czy to są argumenty a = '' i i = 9 wywołania funkcji mapy? Sprawdzono Array.prototype.map () na mdn i nie wygląda na to, że mapa obsługuje takie argumenty ..
Jay Somedon
@JaySomedon są argumentami wywołania funkcji mapy, w pewnym sensie funkcje JavaScript zazwyczaj nie dbają o to i odrzucają parametry, których się nie spodziewają.
Inicjuję
@JaySomedon zobacz także tę odpowiedź i powiązane komentarze codegolf.stackexchange.com/a/2684/21348
edc65
@ edc65 aha Rozumiem! To fajnie! Więc tutaj, gdy javascript ocenia argumenty takie jak i = 9 w map (), faktycznie tworzy zmienną globalną, a następnie przypisuje do niej 9?
Jay Somedon
11

Uwaga: Wszystkie te techniki przypisują ciąg alfabetu zmiennej a.


Jestem 99% pewien, że najkrótszą drogą do osiągnięcia tego celu w JavaScript jest:

a="abcdefghijklmnopqrstuvwxyz" // 30 bytes

Ale istnieje kilka innych interesujących metod. Możesz użyć kompresji ciągów:

a=btoa`i·?yø!?9%?z)ª»-ºü1`+'yz' // 31 bytes; each ? represents an unprintable

Możesz pobrać skompresowany ciąg z atob`abcdefghijklmnopqrstuvwx`. 'yz'Należy dodać ręcznie, ponieważ jeśli skompresować cały ciąg, a wynik jest tylko 27 bajtów, to okaże się, jak abcdefghijklmnopqrstuvwxyw==.

Uważam, że najkrótszym sposobem, aby to zrobić programowo, jest również metoda, którą zasugerowałeś:

for(i=97,a='';i<123;)a+=String.fromCharCode(i++) // 48 bytes

Możesz to zrobić za pomocą funkcji ES6 ( ciągi szablonów`` , operator rozkładania... ), jeśli chcesz:

a=[...Array(26)].map(_=>String.fromCharCode(i++),i=97).join`` // 61 bytes
a=[...Array(26)].map((_,i)=>String.fromCharCode(i+97)).join`` // also 61 bytes
a=[...Array(i=26)].map(_=>String.fromCharCode(++i+70)).join`` // again, 61 bytes

Możesz zrobić jedno lepiej ze zmienną zamiast .join``:

[...Array(26)].map(_=>a+=String.fromCharCode(i++),i=97,a='') // all 60 bytes
[...Array(26)].map((_,i)=>a+=String.fromCharCode(i+97),a='')
[...Array(i=26)].map(_=>a+=String.fromCharCode(++i+70),a='')

Lub ES7 ze zrozumieniem tablicowym , który jest kolejnym bajtem krótszym:

a=[for(_ of Array(i=26))String.fromCharCode(++i+70)].join`` // 59 bytes

Wcześniejsze utworzenie zmiennej zapisuje kolejny bajt:

a='',[for(_ of Array(i=26))a+=String.fromCharCode(++i+70)] // 58 bytes

Również String.fromCharCodeakceptuje wiele argumentów i będzie je automatycznie dołączyć. Możemy więc zagrać w golfa w każdej wersji ES6 do 57 bajtów:

a=String.fromCharCode(...[...Array(26)].map(_=>i++,i=97)) // all 57 bytes
a=String.fromCharCode(...[...Array(26)].map((_,i)=>i+97))
a=String.fromCharCode(...[...Array(i=26)].map(_=>++i+70))

A ES7 jeden do 55:

a=String.fromCharCode(...[for(_ of Array(i=26))++i+70]) // 55 bytes

Jeśli chcesz dowiedzieć się więcej o zakresach golfowych, zapoznaj się z tym zestawem wskazówek . Jest też jedno ze zrozumieniem tablicowym ES7 .

EDYCJA: Jak zauważył edc65, większość z nich staje się krótsza przy użyciu i.toString(36)zamiast String.fromCharCode(i):

for(i=9,a='';++i<36;)a+=i.toString(36) // 38 bytes
a=[...Array(26)].map(_=>(++i).toString(36),i=9).join`` // 54 bytes
[...Array(26)].map(_=>a+=(++i).toString(36),i=9,a='') // 53 bytes
i=9,a=[for(_ of Array(26))(++i).toString(36)].join`` // 52 bytes
i=9,a='',[for(_ of Array(26))a+=(++i).toString(36)] // 51 bytes

Uważam, że ten jest najkrótszy z możliwych, który można wywołać jako wartość zwracaną przez funkcję:

eval("for(i=9,a='';++i<36;)a+=i.toString(36)") // 46 bytes

Jest trzy bajty krótszy niż ręczne zwracanie go z funkcji:

x=>eval("for(i=9,a='';++i<36;)a+=i.toString(36)") // 49 bytes
x=>{for(i=9,a='';++i<36;)a+=i.toString(36);return a} // 52 bytes

Oczywiście x=>"abcdefghijklmnopqrstuvwxyz"nadal bije wszystko inne.

ETHprodukcje
źródło
Naprawdę podoba mi się, dokąd to zmierza - chciałbym tylko móc ES7 w chromie :(
Charlie Wynn
2
@CharlieWynn Tak, szkoda, że ​​nie wszystkie przeglądarki obsługują wszystkie najnowsze funkcje. Ale w końcu Chrome nie został zbudowany w ciągu jednego dnia;;)
ETHprodukcje
Większość z tych rozwiązań można skrócić za pomocą .toString zamiast String, .fromCharCode. Zobacz moją odpowiedź
edc65,
1
@CharlieWynn Myślę, że Chrome Beta obsługuje teraz wszystkie ES7 i wszystkie ES6, z wyjątkiem modułów i optymalizacji ogonów.
gcampbell
Oto 42-bajtowy, który można wywołać jako wartość zwracaną przez funkcję: (f=(i=9)=>++i<36?i.toString(36)+f(i):'')()
Rick Hitchcock
7

Oto inne podejście, 51-bajtowe wyrażenie ES6:

String.fromCharCode(...Array(123).keys()).slice(97)

Oczywiście 50 bajtów.

Neil
źródło
Dla wielkich liter: String.fromCharCode (... Array (91) .keys ()).
Slice
1

36 bajtów, używając sztuczki, o której właśnie się dowiedziałem (z tego postu: /codegolf//a/176496/64538 ):

for(i=9;++i<36;)name+=i.toString(36)

window.name domyślnie jest pustym ciągiem.

Oczywiście jest to nawet mniej praktyczne niż rozwiązanie 38-bajtowe, ponieważ używa dłuższej nazwy zmiennej.

12Me21
źródło
1

Używanie tego, co może, ale nie musi być zdefiniowane w zakresie globalnym

39 bajtów dla właściwości obiektu na dopasowanie tablicy a-z

a=`${Object.keys(top)}`.match(/[a-z]/g)

48 bajtów dla nieposortowanych Set

a=new Set(`${Object.keys(top)}`.match(/[a-z]/g))

55 bajtów dla posortowanego Set

a=new Set(`${Object.keys(top)}`.match(/[a-z]/g).sort())

67 bajtów na posortowany ciąg

a=[...new Set(`${Object.keys(top)}`.match(/[a-z]/g).sort())].join``
guest271314
źródło