从String.slice()方法返回的奇怪结果

时间:2018-12-25 18:59:24

标签: javascript string slice

我的情况是将一个字符串分成字符串数组,然后将每三个字符转换为一个字符串。 (例如“ 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'。为什么?

6 个答案:

答案 0 :(得分:6)

问题在于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'));

答案 1 :(得分:5)

多田!与其将字符串转换为数组并遍历每个字符等待索引为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'));

答案 2 :(得分:1)

使用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'));

答案 3 :(得分:0)

嘿,所以我找出了问题所在。当您在键上添加3时,它会将结果串联起来,给您0、03、3、33、6、63作为键,而键+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'));

答案 4 :(得分:0)

除了在字符串中添加数字(对象的键是什么)之外,您还可以使用生成器来任意分割字符串。

function* translate (string, size) {
    var i = 0;
    while (i < string.length) yield string.slice(i, i += size);
}

console.log([...translate('xxxyyyzzz', 3)]);

答案 5 :(得分:0)

再共享一个与字符数无关的解决方案(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;
  }, []);