该题目可以描述为:
[abecs] => [A-Bb-Eee-Cccc-Sssss]
[AbeCd] => [A-Bb-Eee-Cccc-Ddddd]
该题目实现起来也比较简单,用传统的js代码实现如下:
1 function accum(s) { 2 3 s = s.toUpperCase().split(""); 4 5 for(var i=0,l=s.length; i<l; i++) { 6 7 var tmp = s[i].toLowerCase(); 8 9 for(var j=0; j<i; j++){ 10 s[i] += tmp; 11 } 12 } 13 return s.join("-"); 14 }
for循环可以使用map方法来代替,所以最佳解决方案如下:
function accum(s) { return s.split('').map((x,index) => x.toUpperCase()+Array(index+1).join(x.toLowerCase())).join('-'); }
当然,看起来简洁了多,实际上是es6的语法糖,解决问题的思路都是一样的,这里不就此展开讨论。这里只说一下重复字符串如何实现
第一个方法里面是通过for循环来实现重复字符串,这当然可以,但是不优雅。最佳解决方案里用了一个很巧妙的方法:
Array(index+1).join(x.toLowerCase());
Array(index+1)创建了一个长度为index+1的数组,其中的每一项都为undefined。创建完数组之后,用join方法将该数组拼接成字符串;
看一下MDN对join的描述:
所有的数组元素被转换成字符串,再用一个分隔符将这些字符串连接起来。如果元素是undefined 或者null, 则会转化成空字符串
因为数组元素为undefined,所以最终的字符串其实显示的是index个分割符,这就从另一种方法实现了重复字符串
另外的一些方法实现重复字符串,大多是自己写了repeat函数,用的是Array.from方法
const repeat = (s, n) => Array.from({length: n}, () => s).join("")
Array.from可以将类数组转成真正的数组。接受3个参数:
第一个参数是想要转换成真实数组的类数组对象或可遍历对象
类数组对象:拥有一个 length
属性和若干索引属性的任意对象(MDN的解释)---其实只要拥有length属性就可以认为是类数组
可遍历对象:是指实现了Iterator接口的对象,即可以通过for...of进行遍历的对象,关于Iterator,这里不详介绍,以后会专门说
第二个参数是一个函数,如果指定了,则最后生成的数组会经过该函数的加工后再返回
第三个参数是执行第二个参数时的this值
结合定义,就可以知道上面代码的作用,生成一个长度为n的数组,然后数组的每一项替换成字符s,在通过join返回,实现重复字符串n次
小结:es6里有很多激动人心的特性,比如generator,比如块作用域的引入,还有各种甜甜语法糖,善用一些es6的特性可以让代码更简洁,期待es6在浏览器端能快速普及