JS算法总结

前一段时间在 codewars 上做了一些 Javascript 的算法,主要是和数组方法和正则表达式有关,写篇博客来记录一下,否则这里面包含的知识真的忘得太快了。。。

1. Your order,please.

给定一段顺序错误的字符串,字符串里每个单词都包含一个数字代表着这个单词在句子中正确的位置,返回排序后的字符串。

function order(words){
return words.split(‘ ‘).sort(function(a, b){

return a.match(/\d/) - b.match(/\d/);

}).join(‘ ‘);

sort(function(a,b){ return a - b;})sort 中的比较函数,可以决定在排好序的数组中两个参数的位置。如果要 a 在前则要返回一个负数(升序排列),反之要返回正数(降序排列)。

2.Where my anagrams at?

在数组中找到一个元素,拥有和字符串完全相同的字母。

function anagrams(word, words) {
word = word.split(‘’).sort().join(‘’);
return words.filter(function(v) {return word == v.split(‘’).sort().join(‘’);});
}

filter()返回一个满足回调函数的新数组

3.Vasya - Clerk

一队人在电影院门口排队买票,他们手上有 25,50,100 三种纸币,你作为售票员一开始没有钱。写一个函数判断是否你有足够的零钱把票卖给每一个人
挺有意思的一道题,要记住你只有三种面值的纸币,所以需要把你收到的 25 50 100 纸币的个数分别记录。

function tickets(peopleInLine) {
var bills = [0, 0, 0]
for (var i = 0; i < peopleInLine.length; i++) {
switch (peopleInLine[i]) {
case 25:
bills[0]++
break
case 50:
bills[0]–
bills[1]++
break
case 100:
bills[1] ? bills[1]– : bills[0] -= 2
bills[0]–
break
}
if (bills[0] < 0) {
return ‘NO’
}
}
return ‘YES’

4.Triple trouble

function tripledouble(num1, num2) {
for (let i = 0; i < 10; i++) {

if (new RegExp(\`${i}{3}\`).test(num1) && new RegExp(\`${i}{2}\`).test(num2)) {
  return 1;
}

}
return 0;
}

给你两串数字,若满足:第一串中有一个数字出现三次,第二串中那个同样的数字也出现了两次就返回 true

RegExp(`\${i}{3}`)`

RegExp(“n{X}”) n{X,} 量词匹配包含 X 个 n 的序列的字符串。
es6 表达式模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量(感觉有点像 JSP 里的 EL 表达式呢)。

test() 方法用于检测一个字符串是否匹配某个模式.如果字符串 string 中含有与 RegExpObject 匹配的文本,则返回 true,否则返回 false。
所以这里的语句 RegExp(\\${i}{3}`).test(num1)就是在 num1 这个字符串中看是否有 3 个 i(1-10)~

5.Equal Sides Of An Array

找出使数组呈现中心对称的那个元素([1,2,3,4,3,2,1] => 4)

中心对称的那个元素左右两边必然相等,利用这个特点就可以了。

function findEvenIndex(arr){
for(var i=1; i<arr.length-1; i++) {

if(arr.slice(0, i).reduce((a, b) =>  a+b) === arr.slice(i+1).reduce((a, b) =>  a+b)) {
  return i;
}

}
return -1;
}

arrayObject.slice(start,end) 方法可从已有的数组中返回选定的元素。

arr.reduce([callback, initialValue])

reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值。
参数

callback 执行数组中每个值的函数,包含四个参数:
previousValue
上一次调用回调函数返回的值,或者是提供的初始值(initialValue)
currentValue
数组中当前被处理的元素
currentIndex
当前被处理元素在数组中的索引, 即 currentValue 的索引.如果有 initialValue 初始值, 从 0 开始.如果没有从 1 开始.
array
调用 reduce 的数组
initialValue
可选参数, 作为第一次调用 callback 的第一个参数。

reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:

previousValu 上一次值
currentValue 当前值
currentIndex 当前值的索引
array 数组

reduce 是如何工作的

例如执行下面的代码

[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array){
return previousValue + currentValue;
});

|                 | previousValue  | currentValue | index |return value|
| ------          | -----          | ----         |----   |
| first call      | 0              | 1            |   1   | 1        |
| second call     | 1              | 2            |   2   | 3        |
| third  call     | 3              | 3            |   3   | 6        |
| fourth call     | 6              | 4            |   4   | 10       |

当有initialValue时,previousValue 的初始值为initialValue,并且 index 从 0 开始回调

还可以用箭头函数(es6 新增)来写 callback
ES6 允许用=>来写函数
var f = v =>v = var f = function(v) {return v;};

当参数有多个或者没有时,要用小括号()包裹,如果箭头函数的代码块部分多于一条语句,就要使用大括号{}将它们括起来,并且使用 return 语句返回。由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。

var sum = (num1, num2) => num1 + num2;等于
var sum = function(num1, num2) {

return num1 + num2;

};

返回对象

var getTempItem = id => ({ id: id, name: “Temp” });

总结: 对那些数组方法还有正则的用法太不熟悉了..很多时候第一反应都是用 for 做循环,大一 c 留下的坑。ES6 以后要从头到尾看一遍,很有用的说。