【问题标题】:Strange results returned from String.slice() method从 String.slice() 方法返回的奇怪结果
【发布时间】:2019-05-24 07:03:28
【问题描述】:

我的情况是将一个字符串分成字符串数组,然后将每三个字符转换为一个字符串。 (例如“xxxyyy”->['xxx','yyy']

const translate = function (RNA) {
    var arrRna = Array.from(RNA);
    var arr = [];
    for (var key in arrRna) {
        if ((key % 3) == 0) {
            var temp = RNA.slice( key,  (key+3));
            arr.push(temp);
        }

    }
    return arr;
}

console.log(translate('xxxyyyzzz'));

预期结果:['xxx','yyy','zzz']

但我想要的结果是:[ 'xxx', 'yyyzzz', 'zzz' ]

另外,我注意到 slice 方法在第一次迭代中按预期工作,但在那之后,奇怪的结果 --> 'yyyzzz'。为什么??

【问题讨论】:

  • 您不应该在数组上使用for...in 循环,考虑到(不幸的是)向内置类型添加可枚举方法的常见做法(以及键是字符串而不是下面的答案中指出的数字)。

标签: javascript string slice


【解决方案1】:

问题在于for..in 循环遍历属性名称,并且属性名称始终是字符串。因此,例如,当key 为 3 时:

var temp = RNA.slice( key,  (key+3));

评估为

var temp = RNA.slice('3',  '33');

因为+ 连接 当涉及字符串时。你可以先投到Number

const translate = function(RNA) {
  var arrRna = Array.from(RNA);
  var arr = [];
  for (var key in arrRna) {
    key = Number(key);
    if ((key % 3) == 0) {
      var temp = RNA.slice(key, (key + 3));
      arr.push(temp);
    }

  }
  return arr;
}

console.log(translate('xxxyyyzzz'));

或者,您可以使用普通的 for 循环对数组进行分块,其逻辑可能一目了然更容易理解:

const translate = function(RNA) {
  const output = [];
  for (let i = 0; i < RNA.length; i += 3) {
    output.push(RNA.slice(i, i + 3));
  }
  return output;
}

console.log(translate('xxxyyyzzz'));

另一种选择是使用全局正则表达式.match

const translate = RNA => RNA.match(/.{1,3}/g);
console.log(translate('xxxyyyzzz'));

【讨论】:

  • 你是上帝,正则表达式解决方案很有趣
【解决方案2】:

多田!而不是将字符串转换为数组并遍历每个字符以等待索引为 3 的倍数,只需按 3s 计数即可。

function translate(rna) {
  let arr = [];
  
  for (let i = 0; i < rna.length; i += 3) {
    arr.push(rna.slice(i, i + 3));
  }
  
  return arr;
}

console.log(translate('xxxydyyzzzd'));

【讨论】:

    【解决方案3】:

    使用Array.from() 和映射回调来完成整个过程的方法

    const translate = (RNA) => {
      return Array.from({length: Math.ceil(RNA.length/3)}, (_,i)=> RNA.slice(i*3, i*3+3));       
    }
    
    console.log(translate('xxxyyyzzz'));

    【讨论】:

      【解决方案4】:

      嘿,所以我发现了问题所在。当您将 3 添加到键时,它会连接结果以将 0、03、3、33、6、63 作为键和 key+3 为您提供您看到的结果。

      const translate = function (RNA) {
          var arrRna = Array.from(RNA);
          var arr = [];
          for (var key in arrRna) {
              if ((key % 3) == 0) {
                  console.log(key)
                  console.log(key+3)
                  var temp = RNA.slice( key,  (key+3));
                  arr.push(temp);
              }
      
          }
          return arr;
      }
      
      console.log(translate('xxxyyyzzz'));

      解决方案很简单。在键之前添加一个“+”。这种类型将其转换为数字,从而为您提供预期的结果。

      const translate = function (RNA) {
          var arrRna = Array.from(RNA);
          var arr = [];
          for (var key in arrRna) {
              if ((key % 3) == 0) {
                  var temp = RNA.slice( +key,  (+key+3));
                  arr.push(temp);
              }
      
          }
          return arr;
      }
      
      console.log(translate('xxxyyyzzz'));

      【讨论】:

        【解决方案5】:

        除了向字符串添加数字(对象的键是哪些键)之外,您还可以使用生成器对字符串进行任意切片。

        function* translate (string, size) {
            var i = 0;
            while (i < string.length) yield string.slice(i, i += size);
        }
        
        console.log([...translate('xxxyyyzzz', 3)]);

        【讨论】:

          【解决方案6】:

          共享一个独立于字符数的另一种解决方案(3)

          let spltStr = myStr =>
            [...myStr.toLowerCase()].reduce((acc, char) => {
              let last = acc[acc.length - 1];
              !last || last[last.length - 1] !== char
                ? acc.push(char)
                : (acc[acc.length - 1] += char);
              return acc;
            }, []);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-09-02
            • 1970-01-01
            • 2018-01-15
            • 1970-01-01
            • 2012-08-08
            • 2012-12-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多