格式化电话号码,并不像看到的那么简单

问题

给出一个整数数组,长度为10,如:[1,2,3,4,5,6,7,8,9,0],按顺序转换成电话号码字符串,格式如下:

(123) 456-7890

这道问题看似很简单,解决思路也非常明了,我们尝试用javascript来解决这个问题。

 

思路一:拆分组合法

通常的做法是把数组按照输出格式中的各个部分的长度进行分割,如下:

第一组:1,2,3

第二组:4,5,6

第三组:7,8,9,0

Javascript中关于数组分割的函数最常用的是 slice 和 splice, 我们分别尝试使用二者,也能从中体会二者的区别。

 

首先,利用slice:

function createPhoneNumber(numbers){
    return "("+numbers.slice(0,3).join('')+") "+numbers.slice(3,6).join('')+"-"+numbers.slice(6,10).join('');
}

这个解决思路看起来不错,简洁且容易理解。

 

其次,利用splice:

function createPhoneNumber(numbers){
    return "("+numbers.splice(0,3).join('')+") "+numbers.splice(0,3).join('')+"-"+numbers.splice(0,4).join('');
} 

因为每次splice操作都会对原数组造成破坏,这是一个数组剪切操作, 每次splice的参数都需要事先在头脑中计算得出 。该方法在易读方面不如前者。

 

也可以先把数组转换成字符串,然后再拆分组合,看起来更自然一些。

function createPhoneNumber(numbers){
    var numbers=numbers.join('');
    return "("+numbers.substring(0,3)+") "+numbers.substring(3,6)+"-"+numbers.substring(6,10);
}   

 

还可以利用 string.format() 结合 Array.slice()函数达成拆分组合的目的。

function createPhoneNumber(numbers){
  return "({0}) {1}-{2}".format(
    numbers.slice(0,3).join(''),
    numbers.slice(3,6).join(''),
    numbers.slice(6).join('')
  )
}

 

 

思路二:替换法

我们知道最终的电话号码格式为:(xxx) xxx-xxxx

那么是否可以用替换法来实现该函数呢,把上述字符串中的每个x都相应地换成具体数值就可以了。

为此我们需要先构造一个字符串变量:var phoneFormat="(xxx) xxx-xxxx"

然后循环数组,逐个替换掉其中的x即可,我们知道javascript中的replace函数一次只能替换一个字符,充分利用这一点就可以达到我们的目的。

function createPhoneNumber(numbers){
    var phoneFormat="(xxx) xxx-xxxx";
    for(var i=0;i<numbers.length;i++){
        phoneFormat=phoneFormat.replace('x',numbers[i]);
    }
    return phoneFormat;
}   

 

利用 Array.forEach() 函数会使代码更简洁:

function createPhoneNumber(numbers){
    var phoneFormat="(xxx) xxx-xxxx";
    numbers.forEach(d=>{
        phoneFormat=phoneFormat.replace('x',d);
    });
    return phoneFormat;
}

 

 

思路三:利用正则表达式

作为开发人员,第一眼看到这个问题时应该会本能地想到正则表达式,作为文本处理的利器,我们应该时常磨练使用。

电话号码的最终格式为:(xxx) xxx-xxxx , 正则表达式可由三部分组成:(group1) group2-group3。

构建正则表达式如下:

/(\d{3})(\d{3})(\d{4})/

然后利用replace函数输出结果。

function createPhoneNumber(numbers){
  return numbers.join('').replace(/(\d{3})(\d{3})(\d{4})/,'($1) $2-$3');
}

 

正则表达式还可以更简洁一些:

function createPhoneNumber(numbers){
  return numbers.join('').replace(/(...)(...)(.*)/, '($1) $2-$3');
}

 

如果对ES6中的箭头函数比较了解,正则表达式的替换过程还可以写为:

function createPhoneNumber(numbers){
  const p = () => numbers.shift();
  return "(xxx) xxx-xxxx".replace(/x/g, p); 
}

 

思路四:模板字符串

除了以上三种比较传统的方法外,我们还可以借助Javascript的模板技术,实现字符串的输出。

首先把数组转换成字符串,如:1234567890,利用string.substr()或string.substring()字符串处理函数结合模板字符串技术输出结果,其实就是取代传统字符串组合运算(+)。

function createPhoneNumber (numbers) {
  numbers = numbers.join('')
  return `(${numbers.substr(0, 3)}) ${numbers.substr(3, 3)}-${numbers.substr(6, 10)}`
}

 

总结

编程的魅力就在于此,即使面对一个非常简单的电话号码格式化输出问题,我们都可以给出多种解决方法。可以想见,那些更复杂的问题,存在的解决途径一定更加的五光十色,光怪陆离,这也许就是程序编写的魅力所在:通向罗马的道路千条万条,它们的区别不仅仅是代码行数的多少!

 

posted @ 2016-12-12 15:06  王维强  阅读(991)  评论(0编辑  收藏  举报