Reputation: 49
I am a beginner in javascript. I have to perform a recursive function allowing me to output the concatenated names of the array as a string. Has very little, I am there, except my last value is given to me in undefined
const userNames = ['Elon', 'Susan', 'Bill', 'Marika', 'Ryan'];
function name(i) {
if (i < userNames.length) {
var names = userNames[i] + ' - ' + name(++i);
return names;
} else {
console.log(names);
};
}
name(0);
thx all
Upvotes: 1
Views: 1371
Reputation: 135197
First think about the complete domain of your function. Your function accepts an array of strings. The array can contain 0, 1, or more strings and we need your function to work for all cases of that
// contract
joinStrings([]) == ''
joinStrings([a]) == a
joinStrings([a,b]) == a + '-' + b
joinStrings([a,b,c]) == a + '-' + b + '-' + c
Encoding this in a recursive function is trivial in JavaScript – notice there's no need to keep track of array indexes or worry about incrementing an iterator – just think about fulfilling that contract
const joinStrings = xs => {
switch (xs.length) {
case 0: return ''
case 1: return xs[0]
default: return xs[0] + '-' + joinStrings(xs.slice(1))
}
}
console.log(joinStrings([])) // ''
console.log(joinStrings(['a'])) // 'a'
console.log(joinStrings(['a', 'b'])) // 'a-b'
console.log(joinStrings(['a', 'b', 'c'])) // 'a-b-c'
Or course our function could be vastly improved if we allow the user to specify the joining string
const joinStrings = (y, xs) => {
switch (xs.length) {
case 0: return ''
case 1: return xs[0]
default: return xs[0] + y + joinStrings(y, xs.slice(1))
}
}
console.log(joinStrings('&', [])) // ''
console.log(joinStrings('&', ['a'])) // 'a'
console.log(joinStrings('&', ['a', 'b'])) // 'a&b'
console.log(joinStrings('&', ['a', 'b', 'c'])) // 'a&b&c'
Upvotes: 0
Reputation: 2339
The problem is you're mixing your recursion code with the code that you use to print the string at the end. The recursive call hits the 'else' block and falls through to the end of the function. Since there is no 'return' defined at the end of the function, the last 'name(++i)' call evaluates to 'undefined' and this is concatenated to the original string. Here are two solutions:
const userNames = ['Elon', 'Susan', 'Bill', 'Marika', 'Ryan'];
function name(i) {
if (i === userNames.length) {
return '';
}
else {
return userNames[i] + ' - ' + name(++i);
}
}
function printList() {
console.log(name(0))
}
printList();
or
const namesList = ['Elon', 'Susan', 'Bill', 'Marika', 'Ryan'];
function name(i) {
if (i < userNames.length) {
var names = userNames[i] + ' - ' + name(++i);
return names;
} else {
console.log(names);
return '';
};
}
name(0);
Upvotes: 0
Reputation: 7360
First of all, you can use the join()
method:
const userNames = ['Elon', 'Susan', 'Bill', 'Marika', 'Ryan'];
console.log(userNames.join(' - '));
Your recursive function is interesting anyway.
The problem is console.log(names);
is reached when you call name()
with argument 5, and in that function call it is undefined.
You want to console.log()
the result of the first call;
To avoid the last call is undefined, just return an empty string
const userNames = ['Elon', 'Susan', 'Bill', 'Marika', 'Ryan'];
function name(i) {
if (i < userNames.length) {
var names = userNames[i];
let n = name(++i);
return names + (n ? ' - ' + n : '');
} else {
return '';
}
}
console.log(name(0));
Upvotes: 1