Validate US Telephone Numbers
如果傳入字符串是一個有效的美國電話號碼,則返回 true.
用戶可以在表單中填入一個任意有效美國電話號碼. 下面是一些有效號碼的例子(還有下面測試時用到的一些變體寫法):
555-555-5555
(555)555-5555
(555) 555-5555
555 555 5555
5555555555
1 555 555 5555
在本節(jié)中你會看見如 800-692-7753 or 8oo-six427676;laskdjf這樣的字符串. 你的任務(wù)就是驗證前面給出的字符串是否是有效的美國電話號碼. 區(qū)號是必須有的. 如果字符串中給出了國家代碼, 你必須驗證其是 1. 如果號碼有效就返回 true ; 否則返回 false.
function telephoneCheck(str) {
// 祝你好運
var reg = new RegExp(/^(1\s?)?((\(\d{3}\))|\d{3})[\s-]?\d{3}[\s-]?\d{4}$/);
if (str.search(reg)>=0){
return true;
}
return false;
}
str = telephoneCheck("1(555)555-5555");
console.log(str);
創(chuàng)建一個函數(shù),接受兩個或多個數(shù)組,返回所給數(shù)組的 對等差分(symmetric difference) (△ or ⊕)數(shù)組.
給出兩個集合 (如集合 A = {1, 2, 3} 和集合 B = {2, 3, 4}), 而數(shù)學(xué)術(shù)語 "對等差分" 的集合就是指由所有只在兩個集合其中之一的元素組成的集合(A △ B = C = {1, 4}). 對于傳入的額外集合 (如 D = {2, 3}), 你應(yīng)該安裝前面原則求前兩個集合的結(jié)果與新集合的對等差分集合 (C △ D = {1, 4} △ {2, 3} = {1, 2, 3, 4}).
function sym() {
if (arguments.length === 2){
var arr1 = arguments[0];
var arr2 = arguments[1];
var tempArr = [];
return arr1.filter(function(item){
if (Array.from(arr2).indexOf(item) >= 0){
return false;
}
return true;
}).concat(arr2.filter(function(item){
if (Array.from(arr1).indexOf(item) >= 0){
return false;
}
return true;
})).filter(function(item){ //去重
if (tempArr.indexOf(item) >= 0){
return false;
}
else {
tempArr.push(item);
return true;
}
});
}
else if(arguments.length > 2){
var newArgs = [];
var oldArgs = arguments;
newArgs.push(sym(arguments[0], arguments[1]));
for (var i=2; i<oldArgs.length; i++){
newArgs.push(oldArgs[i]);
}
return sym.apply(this, newArgs); //將數(shù)組作為參數(shù)傳遞,需要用apply,而不能直接apply(newArgs),因為參數(shù)并不是數(shù)組
}
}
str = sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]);
console.log(str);
tip1:sym.apply(this, newArgs); //將數(shù)組作為參數(shù)傳遞,需要用apply,而不能直接apply(newArgs),因為參數(shù)并不是數(shù)組;
tip2:注意需要對數(shù)組去重。
Exact Change
設(shè)計一個收銀程序 checkCashRegister() ,其把購買價格(price)作為第一個參數(shù) , 付款金額 (cash)作為第二個參數(shù), 和收銀機中零錢 (cid) 作為第三個參數(shù).
cid 是一個二維數(shù)組,存著當(dāng)前可用的找零.
當(dāng)收銀機中的錢不夠找零時返回字符串 "Insufficient Funds". 如果正好則返回字符串 "Closed".
否則, 返回應(yīng)找回的零錢列表,且由大到小存在二維數(shù)組中.
function checkCashRegister(price, cash, cid) {
var change = [];
//都換成整數(shù),防止浮點數(shù)陷阱。
var VALUE = [1, 5, 10, 50, 100, 500, 1000, 2000, 10000];
var money = (cash - price) * 100;
cid = cid.map(function(item){
item[1] *= 100;
return item;
});
var i = 8;
while (money > 0){
if (i<0){
return "Insufficient Funds";
}
var sum = 0;
while (money>=VALUE[i] && cid[i][1]>0){
money -= VALUE[i];
cid[i][1] -= VALUE[i];
sum += VALUE[i];
}
if (sum>0){
//直接temp=cid的話,修改temp會影響cid的值,影響后面零錢是否用光的判斷
var temp = cid.slice(); // this is how to make a copy
temp[1] = sum / 100;
change.push(temp);
}
i--;
}
//零錢是否用光
for (i=0; i<9; i++){
if (cid[i][1]>0){
return change;
}
}
return "Closed";
}
str = checkCashRegister(19.50, 20.00, [["PENNY", 0.50], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]);
console.log(str);
tips1:數(shù)組是指針!賦值給其它數(shù)組后,是把指針傳遞了過去,新數(shù)組改變會影響原數(shù)組?。?!
console.log('before:' + cid[i]);
var temp = cid;
temp[i][1] = sum / 100;
console.log('after:' + cid[i]);
打印結(jié)果:
before:PENNY,0
freecodecamp.js:28 after:PENNY,0.5
參考:javascript中把一個數(shù)組的內(nèi)容全部賦值給另外一個數(shù)組 - ..._博客園
function updateInventory(arr1, arr2) {
for (var j=0; j<arr2.length; j++){
var i = 0;
//在有序表中尋找位置
while (i<arr1.length && arr2[j][1]>arr1[i][1]){
i++;
}
console.log(i);
if (i===arr1.length){
arr1.push(arr2[j]);
}
else{
//如果存在
if (arr1[i][1] === arr2[j][1]){
arr1[i][0] += arr2[j][0];
}
//如果未存在
else{
var tempArr = arr1.slice(0, i);
tempArr.push(arr2[j]);
arr1 = tempArr.concat(arr1.slice(i));
}
}
}
return arr1;
}
var curInv = [
[21, "Bowling Ball"],
[2, "Dirty Sock"],
[1, "Hair Pin"],
[5, "Microphone"]
];
var newInv = [
[2, "Hair Pin"],
[3, "Half-Eaten Apple"],
[67, "Bowling Ball"],
[7, "Toothpaste"]
];
str = updateInventory(curInv, newInv);
console.log(str);
tips1:
原先寫的如下代碼:
for (var j=0; j<arr2.length; j++){
var i = 0;
//在有序表中尋找位置
while (arr2[j][1][0] > arr1[i][1][0]){
i++;
}
……
}
報錯:
freecodecamp.js:6 Uncaught TypeError: Cannot read property '1' of undefined
一開始以為是不能把arr2視為多維數(shù)組,對其直接取下標。而結(jié)果是,直接把參數(shù)視為多維數(shù)組沒毛病,錯誤是沒限制i的范圍,我越界了?。。?/p>
tips2:
字符串可以直接比較大小,會根據(jù)第一個不同的字符的ascii值碼進行比較,當(dāng)數(shù)字(number)與字符串(string)進行比較大小時,會強制的將數(shù)字(number)轉(zhuǎn)換成字符串(string)然后再進行比較。
例如:
console.log('13'>'3'); // 輸出:false,因為第一位'1'<'3'
把一個字符串中的字符重新排列生成新的字符串,返回新生成的字符串里沒有連續(xù)重復(fù)字符的字符串個數(shù).連續(xù)重復(fù)只以單個字符為準
例如, aab 應(yīng)該返回 2 因為它總共有6中排列 (aab, aab, aba, aba, baa, baa), 但是只有兩個 (aba and aba)沒有連續(xù)重復(fù)的字符 (在本例中是 a).
function swap(array, i, j){
if (i!=j){
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
function permAlone(str){
var count = 0;
function allSort(array, start, end) {
if (start < end - 1){
for (var i=start; i<end; i++){
swap(array, start, i);
allSort(array, start+1, end);
swap(array, start, i);
}
}
//得到一種全排列
else{
//判斷是否有連續(xù)重復(fù)字符
//如果有,返回,不計數(shù)。
for (var j=0; j < array.length - 1; j++){
if (array[j]===array[j+1]){
break;
}
}
if (array[j]!==array[j+1]){
count++;
console.log(array);
}
}
return count;
}
//使用閉包,以便使allSort函數(shù)能直接修改count的值;
//將字符串轉(zhuǎn)換為數(shù)組,否則string類型是無法修改的,函數(shù)只能傳遞形參,
//而數(shù)組作為對象則傳遞的是地址。
allSort(str.split(''), 0, str.length);
return count;
}
console.log(permAlone('aab'));
感覺是前端算法中最難的一道題了,用到遞歸的思路。
Friendly Date Ranges
讓日期區(qū)間更友好!
把常見的日期格式如:YYYY-MM-DD 轉(zhuǎn)換成一種更易讀的格式。
易讀格式應(yīng)該是用月份名稱代替月份數(shù)字,用序數(shù)詞代替數(shù)字來表示天 (1st 代替 1).
記住不要顯示那些可以被推測出來的信息: 如果一個日期區(qū)間里結(jié)束日期與開始日期相差小于一年,則結(jié)束日期就不用寫年份了;在這種情況下,如果月份開始和結(jié)束日期如果在同一個月,則結(jié)束日期月份也不用寫了。
另外, 如果開始日期年份是當(dāng)前年份,且結(jié)束日期與開始日期小于一年,則開始日期的年份也不用寫。
例如:
包含當(dāng)前年份和相同月份的時候,makeFriendlyDates(["2017-01-02", "2017-01-05"]) 應(yīng)該返回 ["January 2nd","5th"]
不包含當(dāng)前年份,makeFriendlyDates(["2003-08-15", "2009-09-21"]) 應(yīng)該返回 ["August 15th, 2003", "September 21st, 2009"]。
請考慮清楚所有可能出現(xiàn)的情況,包括傳入的日期區(qū)間是否合理。對于不合理的日期區(qū)間,直接返回 undefined 即可
function dayAppendix(day){
var str;
switch (day){
case 1:
case 21:
case 31: str = "st";break;
case 2:
case 22: str = "nd";break;
case 3:
case 23: str = "rd";break;
default: str = "th";
}
return str;
}
function makeFriendlyDates(arr) {
var d1 = arr[0].split('-').map(function(item){
return parseInt(item);
});
var d2 = arr[1].split('-').map(function(item){
return parseInt(item);
});
if ((d1[0]>d2[0]) ||
(d1[0]===d2[0] && d1[1]>d2[1]) ||
(d1[0]===d2[0] && d1[1]===d2[1] && d1[2]>d2[2])){
return undefined;
}
var Month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var retArr = [];
var str1 = Month[d1[1]-1] + " " + d1[2];
var str2 = "";
str1 += dayAppendix(d1[2]);
var withinAYear = false;
var deltaY = d2[0] - d1[0];
var deltaM = d2[1] - d1[1];
var deltaD = d2[2] - d1[2];
if ((deltaY===0)||
(deltaY===1 && deltaM<0)||
(deltaY===1 && deltaM===0 && deltaD<0)){
withinAYear = true;
}
var curYear = 2017;
if (d1[0]!==curYear || !withinAYear){
str1 = str1 + ', ' + d1[0];
}
retArr.push(str1);
if (deltaY===0 && deltaM===0 && deltaD===0){
return retArr;
}
if (d1[0]!==d2[0] || d1[1]!==d2[1] || !withinAYear){
str2 += Month[d2[1]-1] + ' ';
}
str2 += d2[2];
str2 += dayAppendix(d2[2]);
if (!withinAYear){
str2 = str2 + ', ' + d2[0];
}
retArr.push(str2);
return retArr;
}
str =makeFriendlyDates(["2010-10-23", "2011-10-22"]);
console.log(str);
tips1:英文日期簡寫是根據(jù)詞尾判別的,即個位是1就是st,個位是2就是nd,個位是3就是rd,其他個位就是th,但11,12,13是例外,都用th。(根據(jù)讀音,eleven總不能加st吧)
tips2:將多個條件寫下來,驗算邏輯,比較容易捋清楚。
tips3:“開始和結(jié)束日期如果在同一個月”指的是同一年&&同一月。
基于原型的語言(如 JavaScript)并不存在這種區(qū)別:它只有對象?;谠偷恼Z言具有所謂原型對象的概念。原型對象可以作為一個模板,新對象可以從中獲得原始的屬性。任何對象都可以指定其自身的屬性,既可以是創(chuàng)建時也可以在運行時創(chuàng)建。而且,任何對象都可以作為另一個對象的原型,從而允許后者共享前者的屬性。
JavaScript構(gòu)造函數(shù)及原型對象 - 王浴昊 - CSDN博客
var Person = function(firstAndLast) {
var arr = firstAndLast.split(' ');
var firstName = arr[0];
var lastName = arr[1];
this.getFirstName = function(){
return firstName;
};
this.getLastName = function(){
return lastName;
};
this.getFullName = function(){
return firstName + ' ' + lastName;
};
this.setFirstName = function(first){
firstName = first;
};
this.setLastName = function(last){
lastName = last;
};
this.setFullName = function(fullName){
firstAndLast = fullName;
var tempArr = fullName.split(' ');
firstName = tempArr[0];
lastName = tempArr[1];
};
};
var bob = new Person('Bob Ross');
console.log(bob);
Map the Debris
返回一個數(shù)組,其內(nèi)容是把原數(shù)組中對應(yīng)元素的平均海拔轉(zhuǎn)換成其對應(yīng)的軌道周期.
原數(shù)組中會包含格式化的對象內(nèi)容,像這樣 {name: 'name', avgAlt: avgAlt}.
至于軌道周期怎么求,戳這里 on wikipedia (不想看英文的話可以自行搜索以軌道高度計算軌道周期的公式).
求得的值應(yīng)該是一個與其最接近的整數(shù),軌道是以地球為基準的.
地球半徑是 6367.4447 kilometers, 地球的GM值是 398600.4418, 圓周率為Math.PI
function orbitalPeriod(arr) {
var GM = 398600.4418;
var earthRadius = 6367.4447;
return arr.map(function(obj){
var R = (obj.avgAlt + earthRadius);
var retObj = {};
retObj.name = obj.name;
retObj.orbitalPeriod = Math.round(2 * Math.PI * R * Math.pow(R/GM, 0.5));
return retObj;
});
}
str = orbitalPeriod([{name : "sputnik", avgAlt : 35873.5553}]);
console.log(str);
Pairwise
找到你的另一半
都說優(yōu)秀的程序員擅長面向?qū)ο缶幊?,但卻經(jīng)常找不到另一半,這是為什么呢?因為你總是把自己局限成為一個程序員,沒有打開自己的思維。
這是一個社群的時代啊,在這里你應(yīng)該找到與你有相同價值觀但又互補的另一半。
譬如:你編程能力強,估值11分,如果以20分為最佳情侶來計算,你應(yīng)該找一個設(shè)計能力強,估值為9分的女生。
那么當(dāng)你遇到一個設(shè)計能力為9分的女生,千萬別猶豫,大膽去表白。千萬別以為后面的瓜比前面的甜哦。
舉個例子:有一個能力數(shù)組[7,9,11,13,15],按照最佳組合值為20來計算,只有7+13和9+11兩種組合。而7在數(shù)組的索引為0,13在數(shù)組的索引為3,9在數(shù)組的索引為1,11在數(shù)組的索引為2。
所以我們說函數(shù):pairwise([7,9,11,13,15],20) 的返回值應(yīng)該是0+3+1+2的和,即6。
function pairwise(arr, arg) {
var flag = [];
var sum = 0;
for (var i=0; i<arr.length; i++){
if (flag[i]){
continue;
}
for (var j=i+1; j<arr.length; j++){
if (flag[j]){
continue;
}
if ((arr[i]+arr[j])===arg){
flag[i] = true;
flag[j] = true;
sum += i;
sum += j;
break;
}
}
}
return sum;
}
pairwise([1,4,2,3,0,5], 7);