codewars题目记录

1、问题描述:传入一个二维数组[[上车人数,下车人数],…],计算上车下车人数变动后车上剩下的总人数

//我的代码
var number = function(busStops){
  // Good Luck!
  var len = busStops.length;
  var num = 0;
  for(var i = 0; i < len; i++){
    num = num + busStops[i][0] - busStops[i][1];
  }
  return num;
}

//票数最高的代码
const number = (busStops) => busStops.reduce((rem, [on, off]) => rem + on - off, 0);

注意点
1)第一种代码是最容易想到的,最普遍的代码,但第二种灵活运用数组的迭代方法Array.reduce(Function),reduce()方法对数组的每一个元素执行函数,并返回一个值,在第二种代码中传入参数:总数(初始值/先前返回值),每次上下车的人数,总数的初始值。
2)箭头函数(匿名函数):

x => x * x
//相当于
function (x) {
    return x * x;
}

箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ … }和return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ … }和return,当参数不止一个时,用括号括起来。
如果要返回一个对象,就要注意,如果是单表达式,这么写的话会报错:

// SyntaxError:
x => { foo: x }

因为和函数体的{ … }有语法冲突,所以要改为:

// ok:
x => ({ foo: x })

箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略。

2、问题描述:将一个数组中的0移到数组末尾,其他元素保持顺序

//我的代码
var moveZeros = function (arr) {
  var len = arr.length;
  for (var i = 0; i < len; i++) {
    if (arr[i] === 0) {
       arr.splice(len, 0, arr[i]);
       arr.splice(i, 1);
       i--;
       len--;
    }
  }
  return arr;
}

//票数最高的代码
var moveZeros = function (arr) {
  return arr.filter(function(x) {return x !== 0}).concat(arr.filter(function(x) {return x === 0;}));
}

注意点:
1)第一种代码有个地方很容易出错,经常会将 len-- 这一步忘记,使代码在后面会出现无限循环的情况,导致浏览器崩溃,第二种代码巧妙地将数组中为0和不为0的部分分割,并合并数组!
2)Array.filter()能筛选出数组中符合条件的元素,Array.concat()来连接数组。

3、问题描述:根据不同人数的姓名数组,返回对应数组长度的字符串

//我的代码
function likes(names) {
  // TODO
  var len = names.length;
  var piece = " likes this";
  var Piece = " like this";
  var noone,First,Second,Third,num;
  switch(len){
      case 0:
        noone = "no one";
        noone += piece;
        return noone;
      case 1:
        First = names[0];
        First += piece;
        return First;
      case 2:
        First = names[0];
        Second = names[1];
        First += " and " + Second + Piece;
        return First;
      case 3:
        First = names[0];
        Second = names[1];
        Third = names[2];
        First += ", " + Second + " and " + Third + Piece;
        return First;
      default:
        First = names[0];
        Second = names[1];
        num = len - 2;
        First += ", " + Second + " and " +  num + " others" + Piece;
        return First;   
    }
}

//票数最高的代码
function likes(names) {
  names = names || [];
  switch(names.length){
    case 0: return 'no one likes this'; break;
    case 1: return names[0] + ' likes this'; break;
    case 2: return names[0] + ' and ' + names[1] + ' like this'; break;
    case 3: return names[0] + ', ' + names[1] + ' and ' + names[2] + ' like this'; break;
    default: return names[0] + ', ' + names[1] + ' and ' + (names.length - 2) + ' others like this';
  }
}

//另一种代码
function likes (names) {
  var templates = [
    'no one likes this',
    '{name} likes this',
    '{name} and {name} like this',
    '{name}, {name} and {name} like this',
    '{name}, {name} and {n} others like this'
  ];
  var idx = Math.min(names.length, 4);
  return templates[idx].replace(/{name}|{n}/g, function (val) {
    return val === '{name}' ? names.shift() : names.length;
  });
}

注意点
1)第一种代码声明了太多的变量,使代码看起来过于繁杂,当直接将声明的变量相加时,即为第二种代码,第三种代码采用了模板字符串,匹配模板字符串中的{name}和{n},如果为{name},则将字符串数组的首个元素移除并返回,若为{n},则返回剩余元素的个数(此时前面的元素都被移除了)。

4、问题描述:给出一个数组,数值为0或1,将其连成的二进制转化为十进制

//我的代码
const binaryArrayToNumber = arr => {
  // your code
  var len = arr.length;
  var num = 0;
  for(var i = 0; i < len; i++){
    num += arr[i] * Math.pow(2,len-1-i);
  }
  return num;
};

//票数最高的代码
const binaryArrayToNumber = arr => parseInt(arr.join(''),2);

注意点:
1)第一种的代码思想是对每位进行2的相应次方运算并结果相加,而第二种代码将数组转换为字符串并运用方法将二进制转为十进制。

5、问题描述:根据一个模板将数值数组串成一个字符串

//我的代码
function createPhoneNumber(numbers){
  return "(" + numbers[0] + numbers[1] + numbers[2] + ")" + " " + numbers[3] + numbers[4] + numbers[5] + "-" + numbers[6] + numbers[7] + numbers[8] + numbers[9];                         
}

//票数最高的代码
function createPhoneNumber(numbers){
  numbers = numbers.join('');
  return '(' + numbers.substring(0, 3) + ') ' 
      + numbers.substring(3, 6) 
      + '-' 
      + numbers.substring(6);
}

//另一种代码
function createPhoneNumber(numbers){
  var format = "(xxx) xxx-xxxx";
  
  for(var i = 0; i < numbers.length; i++)
  {
    format = format.replace('x', numbers[i]);
  }
  
  return format;
}

//第四种代码
function createPhoneNumber(numbers){
  return numbers.join(‘‘).replace(/(...)(...)(.*)/, ($1) $2-$3);
}

注意点:
1)第一种代码简洁明了,但当数组元素多时,就会特别麻烦低效,第二种代码将数组转化为字符串,并通过str.substring()来提取字符串中的字符,第三种代码通过定义字符串格式再进行逐个替换,第四种代码通过$1,$2,$3来替代3个表达式,分别对应字符串的前3个字符,中间3个字符和最后的所有字符进行替换。

6、问题描述:将字符串中的字母分别用对应的数字代替,不区分大小写,对字符串非字母的部分忽略

//我的代码
function alphabetPosition(text) {
  var t = text.split("");
  for (var i = 0; i < t.length; i++) {
      var x = t[i].charCodeAt();
      if ((x >= 65 && x <= 90) || (x >= 97 && x <= 122)) {
          t[i] = (x >= 97 ? x - 96 : x - 64).toString();
      } else {
          t.splice(i--, 1);
      }
  }
  text = t.join(" ");
  return text;
}

//票数最高的代码
function alphabetPosition(text) {
  return text
    .toUpperCase()
    .match(/[a-z]/gi)
    .map( (c) => c.charCodeAt() - 64)
    .join(' ');
}

注意点:
1)第一种方法为常规解法,第二种方法通过将字符串全转换为大写并将字母都转换为对应数值再串成字符串,通过数组和字符串的转换和对应方法来解题。

总结:
1)在很多情况下可以用数组的迭代方法来达到目的,使代码更加简短整洁,而不是凡事都用for循环
2)在有必要的时候声明变量,但不要过多声明变量,会使代码过于繁杂。
3)在写代码过程中要对每一个变量的值做到心里有数,往往当变量的值改变时我们却未曾注意,导致结果与预期不同。
4)熟练掌握数组和字符串的各种方法和两者之间的转换。

猜你喜欢

转载自blog.csdn.net/qq_46469137/article/details/107230835