Garth Marenghi
Garth Marenghi

Reputation: 2037

How is this array join producing strings of characters?

A problem over at CodeWars is to write a function, accum(s), that does the following:

accum("abcd");    // "A-Bb-Ccc-Dddd"
accum("RqaEzty"); // "R-Qq-Aaa-Eeee-Zzzzz-Tttttt-Yyyyyyy"
accum("cwAt");    // "C-Ww-Aaa-Tttt"

An answer to this problem is the following:

function accum(s) {
  return s.split('').map((x,index) => x.toUpperCase()+Array(index+1).join(x.toLowerCase())).join('-');
}

I am particularly interested in what x.toUpperCase()+Array(index+1).join(x.toLowerCase()) does.

If I write it in pieces, Array outputs []. Array(1) outputs [ ]. Array(2) outputs [ , ]. That's seems... odd.

Even stranger, 'a' + Array() outputs a, 'a' + Array(1) seemingly outputs a as well, 'a' + Array(2) outputs a,, 'a' + Array(3) outputs a,,. Notice that the angular brackets are gone. I.e., it is not an array. Again, that seems... odd.

Even better, 'a' + Array() + 'b' outputs a, 'a' + Array(1) + 'b' outputs a, 'a' + Array(2) + 'b' outputs ab.

My question is if someone could explain what is happening exactly in all these three cases. In the first case, why does there seem to be a space added going from Array() to Array(1)? And why does Array(2) not output [,], but [ , ]?

And what happens when a letter is concatenated with Array(n)? What is returned by Array(n) in this case?

Upvotes: 1

Views: 1700

Answers (1)

Soviut
Soviut

Reputation: 91555

This works because it's creating an array with a certain number of elements which are undefined by default, then joining them using a letter as a delimiter.

Think of what it would be like if you joined an array of blank strings with a comma delimiter:

// join with blank delimiter
console.log(['A', 'B', 'C'].join(''));

// join with comma delimiter
console.log(['A', 'B', 'C'].join(','));

// join blank strings with comma delimiter
console.log(['', '', ''].join(','));

// join blank strings with letter delimiter
console.log(['', '', ''].join('a'));

// join undefined with letter delimiter
console.log([undefined, undefined, undefined].join('a'));

// join array of undefined with letter delimiter
console.log(Array(3).join('a'));

Notice that the last element in the array doesn't get a delimiter, so the result will always have one less character compared to the array length. This is why they use Array(index+1) to make the temporary array larger to accommodate an extra delimiter.

Upvotes: 4

Related Questions