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!!!
他们两个是不相等的!
网友评论