Ivonne Terrero Ivonne Terrero - 3 months ago 9
Javascript Question

Implementing a join function that is being passed 3 arguments

I'm looking to complete this exercise fLet's write a function called join that works just like the built-in join, but using reduce!



Let's write a function called join that works just like the built-in join, but using reduce! If you're unfamiliar with the built-in version of join, this is how it works:

["the", "quick", "brown", "fox"].join(" "); // => "the quick brown fox"
["one", "two", "three"].join(":"); // => "one:two:three"
Part One: First, write a function called joinWith that takes three arguments: the string to join onto, the string that will be joined, and a separator. That is, it should work like this:

function joinWith(onto, next, separator) {
// YOUR CODE HERE
}
joinWith("the quick", "brown", " "); // => "the quick brown"
joinWith("one:two", "three", ":"); // => "one:two:three"
Part Two: Now, using joinWith and reduce, write join:

function join(array, separator) {
// YOUR CODE HERE
}
join(["the", "quick", "brown", "fox"], " "); // => "the quick brown fox"
join(["one", "two", "three"], ":"); // => "one:two:three"





and I have written the following code:



var joinWith = function(start, toAdd, separt){

return reduce(arguments, function(start, toAdd){
return start + separt + toAdd;

}, " ");
}




However I'm not sure why I'm getting the following as a result.



joinWith("one: two", "three", ":");
" :one: two:three::"





Can someone tell me what is happening here and how to I remove the separator from the front of the string and the areas where the separator should not show up.

I greatly appreciate your help.

Answer

What's currently happening:

You don't show your reduce() function's implementation, but assuming it works in the same manner as the standard Array.prototype.reduce() then your output can be explained as follows:

arguments is an array-like object with these values:

["one: two", "three", ":"]

When you call reduce() on arguments, it visits each item in turn as follows:

1st iteration: start is " ", from the last argument to reduce(), and toAdd is "one: two". From that iteration you return the string " :one: two".

2nd iteration: start is " :one: two" (the return value from the previous iteration), and toAdd is "three", and you return " :one: two:three".

3rd iteration: start is " :one: two:three" (the return value from the previous iteration), and toAdd is ":" and you return " :one: two:three::"

What you should do:

You know the function has three arguments, so just use:

function joinWith(start, toAdd, separt) {
  return start + separt + toAdd;
}

But you really want to use reduce():

Well it's really the wrong tool for the job when your specification is to join only two strings, but if you must, you want to use it on all but the last argument to joinWith() - noting that as follows that lets you pass an arbitrary number of strings to join as long as the separator is the last argument:

var joinWith = function(){
  if (arguments.length < 3) return arguments[0];
  var separt = arguments[arguments.length-1];
  return reduce(Array.prototype.slice.call(arguments,0,-1), function(start, toAdd){
    return start + separt + toAdd;
  }); // note: do not pass an initial value
}
    
console.log(joinWith("one: two", "three", ":"));
console.log(joinWith("one","two","three","four","five",":"));
console.log(joinWith("a","b","c","d","e",", "));
console.log(joinWith("x","y"));
    
// Dodgy simulation of your reduce() function for demo purposes only: 
function reduce(arr, cb) {
  return Array.prototype.reduce.call(arr, cb);
}