美文网首页
2020-05-14 5kyu Typoglycemia Gen

2020-05-14 5kyu Typoglycemia Gen

作者: 苦庭 | 来源:发表于2020-05-15 00:51 被阅读0次

https://www.codewars.com/kata/55953e906851cf2441000032/javascript

My answer

ScrambleWords = function(str){
  //start here
  str = str.toLowerCase();
  if(str.length <= 2) return str;

  var words = str.split(" ").map((word)=>{
    if (word.length <= 2) return word;
    // manual matchAll
    var arr = [];
    var string = "";
    for(let i=0; i<word.length; i++) {
      string += word[i];
//实在没办法处理包含两个标点符号的word了,只能出此下策。
      let mat = string.match(/[\-\']/);
      let mat2 = string.match(/[\,\.]/);
      
      let ele;
      let ele2;
      let lastIndex=0;
      if(mat) {
        ele = mat.toString()+"@"+(mat.index+lastIndex);
      }
      if(mat2) {
        ele2 = mat2.toString()+"@"+(mat2.index+lastIndex);
      }
      if(ele && !arr.includes(ele)) {
        arr.push(ele);
        if(mat) lastIndex=mat.index;
      }
      if(ele2 && !arr.includes(ele2)) {
        arr.push(ele2);
        if(mat2) lastIndex=mat2.index;
      }
    }

    word = word.replace(/[\-\'\,\.]/g, "");
    var middle = word.slice(1,-1);
    middle = middle.split("").sort().join("");
    var res = word.substr(0,1)+middle+word.slice(-1);
    
    if(arr.length > 0) {
      res = res.split("")
      for(let i=0; i<arr.length; i++) {  
        let index = arr[i].indexOf("@");
        res.splice(arr[i].slice(index+1), 0, arr[i].substr(0, index));
      }
      res = res.join("");
    }
    return res;
  });
  return words.join(" ");
};

问题?

  • 由于String.prototype.matchAll()需要12.0.0的node.js支持,而codewars用10.x上并没那么新的版本。
  • 没有别的思路,用了很原始很brutal的match()替代办法

Best answer

function ScrambleWords(str) {
  let s = str.replace(/[^a-z ]/g, '').replace(/([a-z])([a-z]+)([a-z])/g, (_,a,b,c)=>a+[...b].sort().join``+c) //我tm直呼内行!
  for (let i = 0; i < str.length; ++i) {
    if (/[^a-z ]/.test(str[i])) s = s.slice(0,i) + str[i] + s.slice(i)
  }
  return s
}

好在哪?

  • 主要的工作都在一行代码里搞定了,然后对照原字符串插入所有非字母非空格的特殊符号就O了
  • .replace()中使用了回调函数,非常厉害的操作。对于replace这个函数,传递给.replace回调的第一个参数是满足整个正则表达式匹配的字符串。之后,捕获分组将作为额外参数传递,每个组一个。然后,将与整个正则表达式匹配的字符串部分替换为回调的返回值。
  • ``反引号de妙用:它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。如join``

Recap

  • 好好掌握一下replace的这种骚用法,正则还得加强。
  • 好好掌握函数名+模板字符串的用法,相当于把字符串当参数直接传入该函数
  • 发现了for(var a in arr)这种遍历用法的问题,它是把arr当作对象来使用的,因此每次得到的a直接用都是等于0(因为该对象的key为0,value才是你想要的数组的单个项)
  • 发现了Object的比较是对指向那个对象的比较,而不是对于当前对象字面值的比较。因此
var a = { x:1, y:2 };
a == { x:1, y:2 }; // false!!!

他们两个是不相等的!

相关文章

网友评论

      本文标题:2020-05-14 5kyu Typoglycemia Gen

      本文链接:https://www.haomeiwen.com/subject/tizfohtx.html