Reputation: 105497
Suppose I need to implement a simple join
function that takes an array and returns a concatenated string of elements separated by a separator. Kind of what built-in method Array.prototype.join
does. All implementations I've seen result in one redundant separator at the beginning or at the end and hence there is a need to trim the string.
For example, I can do it like this:
let s = "";
for (let i=0; i < arr.length; i++) s += sep + arr[i];
// redundant separator at the beginning, need to remove it
s = s.substr(1);
Or like this:
let s = "";
for (let i=0; i < arr.length; i++) s += arr[i] + sep;
// redundant separator at the end, need to remove it
s = s.slice(0, -1);
Is there a better approach that doesn't produce redundant separator? Import that implementation should efficiently handle all cases like empty array etc.
One way I can think of is to put an if
statement inside the loop that checks if it's the first/last element and doesn't add a separator in that case, but that seems to be inefficient. Any ideas?
Upvotes: 2
Views: 146
Reputation: 23955
Using reduce:
function join(arr, sep){
if (!arr.length)
return '';
return arr.reduce((a,b) => a + sep + b);
}
console.log(join([1,2],'^'));
Upvotes: 1
Reputation: 105497
Another possible option is using recursion:
function join(a, separator) {
if (a.length === 0) return '';
function concat(a, n) {
return n > 0 ? concat(a, n - 1) + separator + a[n] : a[n];
}
return concat(a, a.length - 1);
}
One limitation is that it can't handle large strings of tens of thousands character because of call stack size restrictions.
Upvotes: 0
Reputation: 15711
let s = arr[0] || "";
for (let i=1; i < arr.length; i++) s += sep + arr[i];
Add the first element, start looping at the second, adding the separator in front.
As you point out in your question, you could use a condition to only append the separator when needed, removing the need to get rid of the redundant one. The problem is, it might be correct if you are joining two or three values, but having to test in every loop iteration will get costly with big arrays.
Upvotes: 2
Reputation: 386604
For the first element, you could check for the length of the array and take the stringed value or an empty string.
Then loop as Salketer in his answer is doing:
let s = arr.length && arr[0].toString() || '';
for (let i=1; i < arr.length; i++) s += sep + arr[i];
Upvotes: 2
Reputation: 68655
If you want to define it yourself you can iterate till to the length- 1
. After the loop you can add the last item only without separator.
Example
let arr = [1,2,3,4,5];
let sep = '-';
function customJoin(array, separator) {
if(array.length === 0) {
return '';
}
let s = '';
let length = array.length;
for (let i = 0; i < length - 1; i++) {
s += arr[i] + separator;
}
return s + arr[length - 1];
}
console.log(customJoin(arr, sep));
Upvotes: 1