20
\$\begingroup\$

I'm pretty sure there's not a better way to do this but figured it couldn't hurt to ask.

I'm tired of typing out a='abcdefghijklmnopqrstuvwxyz'.

Cool languages have Range('a'..'z') or similar

What can we come up with with JS that's as short as possible??

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

is longer than just the alphabet - but guarantees I don't screw up somewhere.

I'm hoping there's a nasty bit-shifty way to produce a-z in less than 50 characters.

I messed around with i=97;Array(26).map(x=>String.fromChar....i++

but it was always way longer by the time I joined then split the array(26) to be useable


Edit: I've gotten it down to

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

60 bytes

\$\endgroup\$
  • 11
    \$\begingroup\$ @muddyfish, LuisMendo: This is on-topic per meta. \$\endgroup\$ – Doorknob Feb 9 '16 at 21:11
  • 1
    \$\begingroup\$ [...Array(26)].map((q,w)=>String.fromCharCode(w+97)) is 52 bytes and add another 7 for the .join`` \$\endgroup\$ – andlrc Feb 9 '16 at 21:13
  • \$\begingroup\$ Related: stackoverflow.com/questions/3895478/… \$\endgroup\$ – Digital Trauma Feb 9 '16 at 21:19
  • \$\begingroup\$ @dev-null a='';i=97;[...Array(26)].map(b=>a+=String.fromCharCode(i++)) is 60 but takes care of the join how are you doing join in 7 without getting commas in the result? \$\endgroup\$ – Charlie Wynn Feb 9 '16 at 21:19
  • 1
    \$\begingroup\$ @CharlieWynn [...Array(26)].map((q,w)=>String.fromCharCode(w+97)).join`` \$\endgroup\$ – andlrc Feb 9 '16 at 21:23
12
\$\begingroup\$

Alternative to String.fromCharCode

... if you are happy with a lowercase only alphabet.

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
\$\endgroup\$
  • 1
    \$\begingroup\$ Oh dang, that is clever. So it's starting with 10, converting to base 36 and printing it? so a-z! \$\endgroup\$ – Charlie Wynn Feb 10 '16 at 14:46
  • \$\begingroup\$ Are those a='' and i=9 arguments of map function call? Checked Array.prototype.map() on mdn and it doesn't look like map support such arguments.. \$\endgroup\$ – Jay Somedon Jan 22 at 14:10
  • \$\begingroup\$ @JaySomedon those are argument for map function call, in a way, Javascript functions tipically don't care and discard parameters they do not expect. So I initialize a variable I need, while adding a parameter that is of no use for the called function \$\endgroup\$ – edc65 Jan 22 at 15:35
  • \$\begingroup\$ @JaySomedon see also this answer and related comments codegolf.stackexchange.com/a/2684/21348 \$\endgroup\$ – edc65 Jan 22 at 15:40
  • \$\begingroup\$ @edc65 aha I see! That's neat! So here, when javascript evaluates arguments like i=9 in map(), it actually creates a global variable i then assigns 9 to that? \$\endgroup\$ – Jay Somedon Jan 23 at 7:42
11
\$\begingroup\$

Note: All of these techniques assign the alphabet string to variable a.


I am 99% certain that the shortest way to achieve this in JavaScript is indeed:

a="abcdefghijklmnopqrstuvwxyz" // 30 bytes

But there are several other interesting methods. You can use string compression:

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

You can get the compressed string from atob`abcdefghijklmnopqrstuvwx`. The 'yz' must be added manually because if you compress the whole string, while the result is only 27 bytes, it will turn out as abcdefghijklmnopqrstuvwxyw==.

I believe the shortest way to do it programmatically is also the method you suggested:

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

You can do it with ES6 features (template strings ``, spread operator ...) if you want:

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

You can do one better with a variable instead of .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='')

Or ES7 with array comprehensions, which is another byte shorter:

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

Creating the variable beforehand saves yet another byte:

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

Also, String.fromCharCode accepts multiple arguments and will automatically join them. So we can golf each ES6 version down to 57 bytes:

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

And the ES7 one down to 55:

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

If you'd like to learn more about golfing ranges, check out this set of tips. There's also one about ES7's array comprehensions.

EDIT: As edc65 has pointed out, most of these become shorter using i.toString(36) instead of 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

I believe this one is the shortest possible that can be called as a function return value:

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

It's three bytes shorter than manually returning it from a function:

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

Of course, x=>"abcdefghijklmnopqrstuvwxyz" still beats everything else.

\$\endgroup\$
  • \$\begingroup\$ I really like where this is going - just wish I could ES7 in chrome :( \$\endgroup\$ – Charlie Wynn Feb 9 '16 at 21:42
  • 2
    \$\begingroup\$ @CharlieWynn Yes, it's a shame that not all browsers support all the latest features. But after all, Chrome wasn't built in a day... ;) \$\endgroup\$ – ETHproductions Feb 9 '16 at 21:53
  • \$\begingroup\$ Most of these solution can be shortened using .toString instead of String,.fromCharCode. See my answer \$\endgroup\$ – edc65 Feb 9 '16 at 22:42
  • 1
    \$\begingroup\$ @CharlieWynn I think Chrome Beta now supports all of ES7 and all of ES6 except modules and tail call optimisation. \$\endgroup\$ – gcampbell Jun 10 '16 at 10:28
  • \$\begingroup\$ Here's a 42-byter that can be called as a function return value: (f=(i=9)=>++i<36?i.toString(36)+f(i):'')() \$\endgroup\$ – Rick Hitchcock Jul 3 '17 at 23:45
7
\$\begingroup\$

Here's another approach, a 51 byte ES6 expression:

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

50 bytes in upper case of course.

\$\endgroup\$
  • \$\begingroup\$ For upper case: String.fromCharCode(...Array(91).keys()).slice(65) \$\endgroup\$ – jpoppe Jan 31 '17 at 16:27
1
\$\begingroup\$

36 bytes, using a trick I just learned about (from this post: https://codegolf.stackexchange.com/a/176496/64538):

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

window.name is an empty string by default.

Of course, this is even less practical than the 38-byte solution since it uses a longer variable name.

\$\endgroup\$
1
\$\begingroup\$

Using what may or may not be defined at global scope

39 bytes for object properties to array matching a-z

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

48 bytes for an unsorted Set

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

55 bytes for a sorted Set

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

67 bytes for a sorted string

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.