美文网首页
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