1

I am attempting to solve what should be a relatively easy practice problem in JavaScript. The object is to create a function called shiftLetters() that does the following:

  1. Converts a string passed as a parameter to a string array comprised of the single letters within the string.
  2. Use the Array.prototype.map() method to iterate over each single character in the array.
  3. If the character is a space, it should not be transformed.
  4. If the character is alphanumeric, it should be transformed using String.charCodeAt() by advancing one character forward (e.g., F becomes G, f becomes g).
  5. Using String.fromCharCode(), assemble a string such that, for example, 'I cannot tell a lie' is transformed to 'J dboopu ufmm b mjf.'

Here is my code so far:

var shiftLetters = function(string){
  // 1. Convert string to an array of characters.
  const stringArray = string.split('');
  const mappedString = stringArray.map( (char) => {
    for (char in mappedString) {
      // TO BE DONE
    }
  });
}

const example = 'Able was I ere I saw Elba.';

I see the following problems with the above code and I am not sure how to resolve them:

  • Though the string—in this sample, 'Able was I ere I saw Elba.'—is transformed successfully into an array comprised of single characters, e.g. ['A', 'b', 'l', 'e'...], String.prototype.charCodeAt() and String.fromCharCode() are not methods exposed by arrays and cannot be used in that context.
  • In searches on MDN and other online resources, I have been unable to uncover any available methods that can reference an index within an array and get the ASCII character code for that element.

Though I can see that if I did successfully create a transformed array of characters, it would then be a simple matter to employ ```Array.prototype.join()`` to create a string transformed in the way described above. I just haven't been able to figure out how to get to that point.

I would appreciate any insights that can be offered. In the meantime, I will continue my research. If I find the answer, I will post it here.

Thanks in advance for your help.

Sincerely,

Robert Hieger

3 Answers 3

1

You could get the char code, add one and get the new character.

const
    shiftLetters = string => string
        .split('')
        .map(c => c === ' ' || !/[a-z\d]/i.test(c)
            ? c
            : String.fromCharCode(c.charCodeAt(0) + 1))
        .join(''),
    example = 'Able was I ere I saw Elba.';

console.log(shiftLetters(example));

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, Nina, for this chained implementation. I tested this code, and of course, it worked. As it turns out, the only thing that prevented my code from running correctly was that I neglected to placed the square brackets around the regular expression suggested by Danilo above. I do appreciate the elegance and succinctness, however, of the chained implementation you suggest, as well.
1

You don't need the for loop inside the map: you are already iterating over the characters in StringArray. Since the characters are strings, you can use all string methods on them. In this case, you'd need String.fromCharCode and String.charCodeAt.

var shiftLetters = function(string){
  // 1. Convert string to an array of characters.
  const stringArray = string.split('');
  const transformedStringArray = stringArray.map( (char) => {
    if (/[A-Za-z0-9]/.test(char)){
      return String.fromCharCode(char.charCodeAt() + 1);
    } 
    else {
      return char;
    }
  })
  return transformedStringArray.join('');
}

2 Comments

Thank you, Danilo for your thoughtful and swift response. Unfortunately, when I attempt to log the result of this function to the console. the output isundefined. I will continue searching for the cause of this problem. Your response has definitely brought me closer to the answer, however.
Are you sure you didn't miss a return statement somewhere? I set up a repl and with that code and got the desired result.
0

This is about as concise as it gets without being too hard to follow

var shiftLetters = string => (
    string.split('').map( c => (
        String.fromCharCode( c.charCodeAt(0) + !!c.match(/[A-Za-z\d]/) )
    )).join("")
);

Note that I am using implicit returns, hence the lack of an explicit return statement. The trickiest part of this solution is the line

c.charCodeAt(0) + !!c.match(/[A-Za-z\d]/)

In this, we check to see if c is a purely alphanumeric character with match. If it is, match will return a Match object, otherwise we get null. Then, !! will convert truthy/falsey (Match Obj vs. Null) values into a boolean. Finally, when doing arithmetic with booleans in JavaScript, false = 0 and true = 1. So this statement will map each alphanumeric character to the next one, and map all other characters to themselves.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.