PineNuts0
PineNuts0

Reputation: 5234

JavaScript: Fully rotate a string and then rotate the string in the other direction given number input

I have a function which takes a string and returns a function. The returned function takes a number and returns a string. The returned function returns the original string rotated by the given number.

My code below works.

function rotater (str){
  return function (num){

    let strArr = str.split('');
    //console.log(strArr)

    for (let i=0; i<num; i++){
      //console.log(num)

      let element = strArr[0];
      //console.log(element)

      strArr.push(element); 
      strArr.shift()
      //console.log(strArr)
    }
    return strArr.join('')
  }
}

const rotate = rotater('abcde');
rotate(4) // returns 'eabcd' as expected

My issue is with the next test spec. Once a string rotates fully, it will afterwards rotate in the other direction.

Below is test spec:

it('once told to rotate fully will afterwards rotate in the other direction', () => {
    const rotate = rotater('helloWORLD');

    expect(rotate(1)).toEqual('elloWORLDh'); // same as before
    expect(rotate(2)).toEqual('lloWORLDhe'); // same as before

    rotate(10); // max value triggers rotation reversal

    expect(rotate(1)).toEqual('DhelloWORL');
    expect(rotate(2)).toEqual('LDhelloWOR');
    expect(rotate(6)).toEqual('oWORLDhell');

    rotate(10); // max value triggers rotation reversal

    expect(rotate(1)).toEqual('elloWORLDh');
    expect(rotate(2)).toEqual('lloWORLDhe');
    expect(rotate(6)).toEqual('ORLDhelloW');
  });

I'm confused by how to pass the above test spec. Do I need to insert an if statement plus break into my code? Please let me what code is missing to pass the above spec.

Upvotes: 1

Views: 290

Answers (1)

Mark
Mark

Reputation: 92460

You need a way to set the state of the returned function. One way to do that is to include a value that you capture in a closure that indicates the direction. You can then manipulate in the function. For example:

function rotater (str){
  let dir = 1                  // flag captured in closure
  return function (num){
    if (num == str.length) {
        dir *= -1              // manipulate it where appropriate 
    }

I set the flag as positive or negative 1 because then it's really convenient to use slice() (which deals with negative numbers well) instead of splitting and looping with something like:

function rotater (str){
  let dir = 1
  return function (num){
    if (num == str.length) {
        dir *= -1
        return str
    }
    return str.slice(dir * num) + str.slice(0, dir * num)
  }
}

const rotate = rotater('helloWORLD');
console.log(rotate(1)) 

console.log(rotate(10)) 
console.log(rotate(1)) // now reversed DhelloWORL
console.log(rotate(6))

rotate(10)
console.log(rotate(1)) // back to forward elloWORLDh

Upvotes: 1

Related Questions