一个有意思的编程练习站点

前段时间,在csdn上的这篇文章 厌倦了编程书?来试试这3种提高编程技能的有趣方法吧  中看到了一个非常有意思的站点:http://www.codewars.com/dashboard

你能够在上面做一些编程练习,往往是完毕一个小方法或者函数,如今它支持的语言包含:Ruby  、JavaScript 、 CoffeeScript ,据说以后还会会支持其他的一些语言。我做了几道JavaScript 练习,认为挺有意思的。由于在这里,你完毕、提交一些练习之后,能够看到别人提交的答案。你会发现,同一个问题竟有那么多的解决方式,人和人之间的思维方式实在是相差得十万八千里。

就拿我今天做的这个练习来说吧。

题目要求例如以下:

You probably know the "like" system from Facebook and other pages. People can "like" blog posts, pictures or other items. We want to create the text that should be displayed next to such an item.

Implement a function likes(), which must take in input array, containing the names of people who like an item. It must return the display text as shown in the examples:

likes([]); // must return "no one likes this"
likes(['Peter']); // must return "Peter likes this"
likes(['Jacob', 'Alex']); // must return "Jacob and Alex like this"
likes(['Max', 'John', 'Mark']); // must return "Max, John and Mark like this"
likes(['Alex', 'Jacob', 'Mark', 'Max']); // must return "Alex, Jacob and 2 others like this"

看起来挺简单的不是吗?几个if ,else 拼接一下字符串不即可了?基于前几次的经验,我想我总得在当中用上点儿什么聪明的方法吧,不然,把这样的粗暴的写法提交上去还不得被歧视?以下是我的答案:

function likes(names) {
  
  var who;
  if(names.length==0){
      who = "no one";
  }else if(names.length<=2){
      who = names.length==1? names[0]:names[0]+" and "+names[1];
  }else{
      who = names.concat().splice(0,2).join(", ")+
            " and "+( names.length>3? names.length-2+" others":names[2] );
  } 
 return who+( names.length>1? " like":" likes" )+" this";

}

为了不让人歧视,我用了一些自以为聪明的方法,但是说实话,这样看起来仍然怪怪的,仍然不够聪明,甚至看起来有些奇怪。以下是几个我觉得非常聪明、非常优雅的别人的写法:

1、这样的方法,大概非常多人都能想到(我却没想到),简单粗暴,但比 if  else  清爽干净不是吗?

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';
  }
}

2、好聪明的写法啊。

function likes(names) {
  if(names.length >= 4) 
    return templates[4].format(names.slice(0, 2).concat(names.length - 2));
  return templates[names.length].format(names);
}

var templates = {
  0: 'no one likes this',
  1: '{0} likes this',
  2: '{0} and {1} like this',
  3: '{0}, {1} and {2} like this',
  4: '{0}, {1} and {2} others like this'
};

String.prototype.format = function(args) {
  return args.reduce(function(acc, value, idx) {
    return acc.replace('{' + idx + '}', value); 
  }, this).toString();
};

3、与另外一种似乎类似,并且更优雅、更聪明。

function likes(names) {
  var str = [
    'no one likes this',
    '%0 likes this', 
    '%0 and %1 like this', 
    '%0, %1 and %2 like this',
    '%0, %1 and %C others like this'
  ];
  return (names.length > 0) ? 
    str[(names.length < 5 ? names.length : 4)]
      .replace('%0',names[0])
      .replace('%1',names[1])
      .replace('%2',names[2])
      .replace('%C',names.length-2) : 
    str[0];
}


当然,还有人的方法或许更聪明,可是似乎可读性太差了些。比方以下这位:

function likes(names) {
  var c = names.length;
  var s = [0, c && c < 3 ? undefined : 2];
  return !c ? "no one likes this" : names.slice(s[0], s[1]).join(c < 3 ? ' and ' : ', ') + ((c < 3) ? (' like' + ((c == 1) ? 's' : '') + ' this') : (' and ' + (c == 3 ? (names.slice(2, 3)) : (c - 2) + ' others') + ' like this'));
}

不得不让人感叹,这些家伙真是厉害。我想我们在写代码时,倘若时间同意,也应多思考怎样聪明地写。只是啊,也要注意代码的可读性,,毕竟代码是写给人看的,聪明地写代码不等于复杂地写代码。看看上面第三种写法,即清楚明了又巧妙优雅,让人拍手称妙。


原文地址:https://www.cnblogs.com/hrhguanli/p/3905171.html