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

前段时间,在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'));
}

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


你可能感兴趣的:(JavaScript,编程,语言)