1

Working on the following problem:

Create a function called alienLanguage where the input will be a str and the output should capitalize all letters except for the last letter of each word

alienLanguage("My name is John") should return "My NAMe Is JOHn"

This is what I have coded:

function alienLanguage(str){
  var words = str.toUpperCase().split(' ').map(function (a) {
    return a.replace(a[a.length - 1], a[a.length - 1].toLowerCase())
  });
  return words.join(' ');
}

All of the example test cases work except for the following:

Expected: '\'THIs Is An EXAMPLe\'', instead got: '\'THIs Is An eXAMPLE\'' 

Why is the e in eXAMPLE turning lowercase? Shouldn't everything automatically turn upperCase ?

edit: I just realized that there are 2 e's and the first one is being replaced. How can I replace the last e? and isn't the last character specified already?

jalexyep
  • 89
  • 8

7 Answers7

2

isn't the last character specified already?

No, you've only specified what character to replace, not where. replace searches the string for the expression.

How can I replace the last e?

Don't use replace at all. It does construct a new string anyway, and you can do that much easier:

function alienLanguage(str) {
  return str.split(' ').map(function(a) {
    return a.slice(0, -1).toUpperCase() + a.slice(-1).toLowerCase();
  }).join(' ');
}

You also could use replace, but would use it with regular expression:

function alienLanguage(str) {
  return str.toUpperCase().replace(/.\b/g, function(last) {
//                                 ^^^^^^ matches all characters before a word boundary
    return last.toLowerCase();
  });
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
2

You don't need to split the string into words. Just use a positive lookahead assertion in your regex to upper-case all letters that are immediately followed by another letter, like this:

function alienLanguage(str){
    return str.replace(/(\w)(?=\w)/g, l => l.toUpperCase())
}
Faust
  • 15,130
  • 9
  • 54
  • 111
0

replace() is searching using a pattern (or regular expression) and it replaces all occurrences.

Instead, you want to truncate and create a new string, which is known as assignment in other languages (but strings in JS are immutable). See here for more details.

Tatsuyuki Ishi
  • 3,883
  • 3
  • 29
  • 41
0

You can use substring. Your replace replaces and replaces the first occurrence of the last character in the words -- definitely what you're after:

function alienLanguage(str){
  var words = str.toUpperCase().split(' ').map(function (a) {
    return a.length ? a.substring(0, a.length - 2) + a[a.length - 1].toLowerCase() : a;
  });
  return words.join(' ');
}
m1kael
  • 2,801
  • 1
  • 15
  • 14
0

As @TatsuyukiIshi said, you need to change the use of replace() for regular assignment. For extra help, here is an updated version of your alienLanguage function:

function alienLanguage(str){
    return str.toUpperCase().split(' ').map(function(word) {
        return word.slice(0, -1) + word.substr(-1).toLowerCase()
    }).join(' ')
}

Fiddle here


Extra notes:

word.slice(0,-1) returns the word minus the last character.

word.substr(-1) returns the last character as a string.

.map() returns an array, so you can call join() directly on the result.

Matt Way
  • 32,319
  • 10
  • 79
  • 85
0

Instead of searching for the letter, just concatenate the uppercase part of the string up to the last letter with the lowercased last letter.

This should do the trick:

function alienLanguage(str) {
  return str.split(' ').map(function(a) {
    return a.slice(0, -1).toUpperCase() + a.slice(-1).toLowerCase();
  }).join(' ');
}
Magnus
  • 17,157
  • 19
  • 104
  • 189
0

Try it.

function alienLanguage(str){
   var words = str.toUpperCase().split(' ').map(function (a) {
   return a.substr(0, a.length - 1) +a[a.length - 1].toLowerCase() + a.substr(a.length - 1 + 1);
   });
  return words.join(' ');
 }
Banshi Lal Dangi
  • 655
  • 3
  • 11