【问题标题】:JavaScript: Fully rotate a string and then rotate the string in the other direction given number inputJavaScript:完全旋转一个字符串,然后在给定数字输入的另​​一个方向上旋转字符串
【发布时间】:2019-06-03 18:03:38
【问题描述】:

我有一个函数,它接受一个字符串并返回一个函数。返回的函数接受一个数字并返回一个字符串。返回的函数返回按给定数字旋转的原始字符串。

我下面的代码有效。

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

我的问题是下一个测试规范。一旦一根弦完全旋转,它就会向另一个方向旋转。

以下是测试规范:

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');
  });

我对如何通过上述测试规范感到困惑。我需要在我的代码中插入 if 语句和 break 吗?请让我通过上述规范缺少什么代码。

【问题讨论】:

    标签: javascript function rotation return reverse


    【解决方案1】:

    您需要一种方法来设置返回函数的状态。一种方法是在闭包中包含一个值,该值指示方向。然后,您可以在函数中进行操作。例如:

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

    我将标志设置为正数或负数 1,因为这样使用slice()(它可以很好地处理负数)非常方便,而不是像这样拆分和循环:

    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

    【讨论】:

    • 追问:当代码碰到console.log(rotate(1))的第二个实例时,怎么知道需要反转?或者换句话说, rotate(10) 如何强制它反转?
    • 第二次调用dir时,变量dir为-1。闭包是您可以在函数中保存状态的一种方式。了解closuresscope
    • @PineNuts0 当您调用rotate(10) 时,它会命中if (num == str.length) 块,并且dir1 更改为-1。这会在切片中使用dir,从而导致切片中出现正值或负值。
    • 哦等等,它将全局目录设置为-1;所以随后的调用使用-1;然后当你再次点击 rotate(10) 时,你乘以 -1 * -1 = 1; 1 现在是新的全局目录...我理解正确吗?
    • 是的 @PineNuts0 是正确的,除了 dir 不是全局的。它是 rotater 函数的本地函数,由于闭包,返回的函数能够看到和操作该函数。 (出于同样的原因,返回的函数能够看到str)。
    猜你喜欢
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    • 2016-05-23
    • 2011-02-02
    • 2019-03-23
    • 2022-12-30
    • 1970-01-01
    • 2020-05-17
    相关资源
    最近更新 更多