7

I can't seem to figure it out how to make a wave from a string in Javascript.

Rules:

  1. The input will always be lower case string.
  2. Ignore whitespace.

Expected result:

wave("hello") => ["Hello", "hEllo", "heLlo", "helLo", "hellO"]

wave (" h e y ") => [" H e y ", " h E y ", " h e Y "]

wave ("") => []

This is as far as I got. Current code will give me an answer ["hello", "hello", "hello", "hello", "hello"]. I'm thinking using second for loop and somehow capitalize each new letter but I'am stumped. Also I would appreciate if answer would avoid using loop inside loop O(n^2). Because of BIG O Scalability.

const wave = (str) => {
    if(typeof str === 'string' && str === str.toLowerCase()){
       for (let index = 0; index < str.length; index++) {
        array.push(str);
    }
    for (let index = 0; index < str.length; index++) {
            console.log(array);   
    }
    }else{
        alert(`${str} is either not a string or not lowercase`);
    }
}
wave("hello");
vahdet
  • 6,357
  • 9
  • 51
  • 106
Arnas Dičkus
  • 522
  • 1
  • 10
  • 26

5 Answers5

10

You could take an outer loop for visiting the characters and if a non space character is found, create a new string with an uppercase letter at this position.

function wave(string) {
    var result = [],
        i;

    for (i = 0; i < string.length; i++) {
        if (string[i] === ' ') continue;
        result.push(Array.from(string, (c, j) => i === j ? c.toUpperCase() : c).join(''));
    }
    return result;
}

console.log(wave("hello"));   // ["Hello", "hEllo", "heLlo", "helLo", "hellO"]
console.log(wave(" h e y ")); // [" H e y ", " h E y ", " h e Y "]
console.log(wave(""));        // []
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

This does it. However, if you have spaces in your string, it will output string without any "waved letter" (since also space is handled):

const wave = (str = '') => {
  return str
    .split('')
    .map((letter, i, arr) => `${arr.slice(0, i)}${letter.toUpperCase()}${arr.slice(i + 1, arr.length)}`.replace(/,/g, ''));
}

console.log(wave('wave'));
console.log(wave('foo bar'));
console.log(wave());
Samuli Hakoniemi
  • 18,740
  • 1
  • 61
  • 74
1

You can take each char in string in for loop and make it uppercase and the append with prefix and post fix string

var array=[];
const wave = (str) => {
    if(typeof str === 'string' && str === str.toLowerCase()){
       for (let index = 0; index < str.length; index++) {
       if (str[index] === ' ') continue;
       waveChar=str.charAt(index).toUpperCase();
       preStr=str.substring(0,index);
       postStr=str.substring(index,str.length-1);
        array.push(preStr+waveChar+postStr);
    }
    
    }else{
        alert(`${str} is either not a string or not lowercase`);
    }
}
wave("hello");
console.log(array);
Vikas
  • 6,868
  • 4
  • 27
  • 41
0

I use modify of String prototype :

for implementation of replaceAt .

// Modify prototype
String.prototype.replaceAt=function(index, replacement) {
    return this.substr(0, index) + replacement+ this.substr(index + replacement.length);
}

function WaveFunction(str) {
 
  var base = str;
  var R = [];
  var n =str.length;
  
  for (var i=0 ; i<n ;i++){
  
   str = base;
   var c=str.charAt(i);
   var res = c.toUpperCase();
   // console.log(res);
   str = str.replaceAt(i, res);
  
   R.push(str);
  }
  return R;
}

var REZ = WaveFunction("hello");

 console.log(REZ);
Nikola Lukic
  • 4,001
  • 6
  • 44
  • 75
Peter Hassaballah
  • 1,757
  • 1
  • 9
  • 18
0

I use tradicional js. This works on 99% off today browsers.

Where answer very pragmatic. I use array access for string ;

Magic is "String.fromCharCode(str.charCodeAt(x) ^ 32);" Make it inverse always when we call this line.

// Also tested UTF-8 non english chars

var index = 0;
var mydata= "helloçφšteti"; 

function wave (str){

 var FINAL = [];
 var newString = "";

 for (var j =0; j < str.length; j++) {
 for (var x =0; x < str.length; x++) { 

   var rez = "";
     if (x == index) {
       rez =  String.fromCharCode(str.charCodeAt(x) ^ 32);
     } else {
       rez =  str[x];
     }
     newString +=  rez ;
  }
  FINAL.push(newString);
  newString = "";
  index++;
 }

 return FINAL;
}

var rezArray = wave(mydata);

console.log(rezArray);

// Just for teory
console.log(Array.from([1, 2, 3], x => console.log(x)));
Nikola Lukic
  • 4,001
  • 6
  • 44
  • 75
  • Your answer uses 2 for loops inside each other. Which is Bad for Scalability O(n^2). According to BIG O notations.[BIG O Cheatsheet](http://bigocheatsheet.com/) – Arnas Dičkus Mar 04 '19 at 13:12
  • You must understand that " for (i = 0; i < string.length; i++) { if (string[i] === ' ') continue; result.push(Array.from(string, (c, j) => i === j ? c.toUpperCase() : c).join('')); }" is ALSO loop in twice. ;) When you call this line : Array.from(string, (c, j) => i === j ? c.toUpperCase() : c).join('')); you work with iterator. – Nikola Lukic Mar 04 '19 at 13:18
  • What you think what is it : console.log(Array.from([1, 2, 3], x => console.log(x))); – Nikola Lukic Mar 04 '19 at 13:19
  • 1
    Thanks, for explanation I wasn't aware of this. – Arnas Dičkus Mar 04 '19 at 13:24
  • Ok , i want to say: you have a right when you say dont' use two arrays ! @Peter Hassaballah give us maybe best solution here. He use replaceAt ! – Nikola Lukic Mar 04 '19 at 13:26
  • where is `replaceAt` from? – Nina Scholz Mar 04 '19 at 13:40
  • It is now integrated but with substr we can do it easy replaceAt(a1,a2) .You can find here : https://stackoverflow.com/questions/1431094/how-do-i-replace-a-character-at-a-particular-index-in-javascript – Nikola Lukic Mar 04 '19 at 14:18
  • 2
    "*`String.fromCharCode(str.charCodeAt(x) ^ 32)`*" is too much magic. It's a nice trick, but **works only on ASCII characters**. Don't do that. There's no reason not to use `.toUpperCase()`. – Bergi Mar 04 '19 at 18:14
  • @Bergi correct, i tested UTF-8 with no latin, it works but only partial. – Nikola Lukic Mar 14 '19 at 18:12