核心提示:本部分一个9道题,给定时间50小时。属于fcc前端学习的“高级编程脚本”题,对于初学者来说,确实算是“高级”了。如果只想着闭门造车,50小时确实也不过分。就题目设的坑和古怪规则来说,估计赶得上实际的情形。有些题目,可能要有一点数理基础才行。

1.如果传入字符串是一个有效的美国电话号码,则返回 true.

用户可以在表单中填入一个任意有效美国电话号码. 下面是一些有效号码的例子(还有下面测试时用到的一些变体写法):

555-555-5555

(555)555-5555

(555) 555-5555

555 555 5555

5555555555

1 555 555 5555

在本节中你会看见如 800-692-7753 or 8oo-six427676;laskdjf这样的字符串. 你的任务就是验证前面给出的字符串是否是有效的美国电话号码. 区号是必须有的. 如果字符串中给出了国家代码, 你必须验证其是 1. 如果号码有效就返回 true ; 否则返回 false.

思路:基本上,就是九个规则并起来。

  1. function telephoneCheck(str) {
  2. // Good luck!
  3. /*
  4. var re1=/^[1-9]\d{9}$/g;
  5. var re2=/^[1-9]\d{2}-[0-9]\d{2}-[0-9]\d{3}$/g;
  6. var re3=/^\([1-9]\d{2}\)[0-9]\d{2}-[0-9]\d{3}$/g;
  7. var re4=/^\([1-9]\d{2}\)\s[0-9]\d{2}-[0-9]\d{3}$/g;
  8. var re5=/^[1-9]\d{2}\s[0-9]\d{2}\s[0-9]\d{3}$/g;
  9. var re6=/^[1]\s[0-9]\d{2}\s[0-9]\d{2}\s[0-9]\d{3}$/g;
  10. var re7=/^[1]\s[0-9]\d{2}-[0-9]\d{2}-[0-9]\d{3}$/;
  11. var re8=/^[1]\s\([0-9]\d{2}\)\s[0-9]\d{2}-[0-9]\d{3}$/;
  12. var re9=/^[1]\([0-9]\d{2}\)[0-9]\d{2}-[0-9]\d{3}$/;
  13. //telephoneCheck("5554555555");
  14. //telephoneCheck("555-555-5555");
  15. //telephoneCheck("(555)555-5555");
  16. //telephoneCheck("(555) 555-5555")
  17. //telephoneCheck("555 555 5555")
  18. //telephoneCheck("1 555 555 5555")
  19. //telephoneCheck("1 555-555-5555")
  20. //telephoneCheck("1 (555) 555-5555")
  21. //telephoneCheck("1(555)555-5555")
  22. *///9个规则
  23. var re=/^[1-9]\d{9}$|^[1-9]\d{2}-[0-9]\d{2}-[0-9]\d{3}$|^\([1-9]\d{2}\)[0-9]\d{2}-[0-9]\d{3}$|^\([1-9]\d{2}\)\s[0-9]\d{2}-[0-9]\d{3}$|^[1-9]\d{2}\s[0-9]\d{2}\s[0-9]\d{3}$|^[1]\s[0-9]\d{2}\s[0-9]\d{2}\s[0-9]\d{3}$|^[1]\s[0-9]\d{2}-[0-9]\d{2}-[0-9]\d{3}$|^[1]\s\([0-9]\d{2}\)\s[0-9]\d{2}-[0-9]\d{3}$|^[1]\([0-9]\d{2}\)[0-9]\d{2}-[0-9]\d{3}$/g;
  24. console.log(str.match(re));
  25. if(str.match(re)){
  26. console.log('true')
  27. return true;
  28. }else{
  29. console.log('false')
  30. return false;
  31. }
  32. }

2.创建一个函数,接受两个或多个数组,返回所给数组的 对等差分(symmetric difference) ( or )数组.

给出两个集合 (如集合 A = {1, 2, 3} 和集合 B = {2, 3, 4}), 而数学术语 "对等差分" 的集合就是指由所有只在两个集合其中之一的元素组成的集合(A △ B = C = {1, 4}). 对于传入的额外集合 (如 D = {2, 3}), 你应该安装前面原则求前两个集合的结果与新集合的对等差分集合 (C △ D = {1, 4} △ {2, 3} = {1, 2, 3, 4}).

补白:题目提示用的是reduce方法:

reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。

回调函数第一次执行时,previousValuecurrentValue 的取值有两种情况,如果 initialValue 在调用 reduce 时被提供,那么第一个 previousValue 等于 initialValue ,并且currentValue 等于数组中的第一个值;如果initialValue 未被提供,那么previousValue 等于数组中的第一个值,currentValue等于数组中的第二个值。

如果数组为空并且没有提供initialValue, 会抛出TypeError 。如果数组仅有一个元素(无论位置如何)并且没有提供initialValue, 或者有提供initialValue但是数组为空,那么此唯一值将被返回并且callback不会被执行。

例子:数组求和——

  1. var total = [0, 1, 2, 3].reduce(function(a, b) {
  2. return a + b;
  3. });
  4. // total == 6

现在来写这个函数。非常感谢此博客提供的思路。

  1. function sym(args) {
  2. var arr=[].slice.call(arguments);//转化为数组;
  3. var temp=arr.reduce(function(prev,cur,index,array){
  4. var a=prev.filter(function(item){
  5. return cur.indexOf(item)==-1;
  6. });//返回前一个结果中,没有出现在下个结果中的部分(数组)
  7. var b=cur.filter(function(item){
  8. return prev.indexOf(item) < 0;
  9. });//返回下个参数中,未有出现在上个结果中的部分(数组)
  10. return a.concat(b);//通通连起来。输出为下个结果
  11. });
  12. console.log(temp);
  13. return temp.filter(function(item,index,array){
  14. return array.indexOf(item) == index;
  15. });
  16. //之前只是比较数组彼此之间的重复,数组内部本身也可能存在重复
  17. //现在解决遗留下来的问题。
  18. return temp.filter(function(item,index,array){
  19. return array.indexOf(item) == index;
  20. });//自身查重只需要让它本身第一次出现在原数组的位置为索引值index,就可以保留且只保留一个。
  21. }

笔者在使用reduce方法用两个for循环进行逐个排查,方法看上去没有错,但会发生内存溢出。在此需要强调下。

3.设计一个收银程序 checkCashRegister() ,其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数.

cid 是一个二维数组,存着当前可用的找零.

当收银机中的钱不够找零时返回字符串 "Insufficient Funds". 如果正好则返回字符串 "Closed".

否则, 返回应找回的零钱列表,且由大到小存在二维数组中.

  1. function checkCashRegister(price, cash, cid) {
  2. var change;
  3. // Here is your change, ma'am.
  4. return change;
  5. }
  6. // Example cash-in-drawer array:
  7. // [["PENNY", 1.01],
  8. // ["NICKEL", 2.05],
  9. // ["DIME", 3.10],
  10. // ["QUARTER", 4.25],
  11. // ["ONE", 90.00],
  12. // ["FIVE", 55.00],
  13. // ["TEN", 20.00],
  14. // ["TWENTY", 60.00],
  15. // ["ONE HUNDRED", 100.00]]
  16. checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]);

可能还要翻译下。panny——1美分,nickel——5美分,dime——1角,quarter,25美分,one:1美元,...5美元,10美元,20美元,100美元。

找钱系统在行业中,为了避免浮点数的不精确,通通采用整数计算。

  1. function checkCashRegister (price, cash, cid) {
  2. // 刚刚好
  3. if(price==cash){
  4. return "No Need Back";
  5. }
  6. // 付款不足
  7. if (price > cash){
  8. return "Need More Money";
  9. }
  10. var base=100;//金额基数
  11. var change=(cash-price)*base; //找零
  12. //定义一个函数,用来求零钱和。
  13. var getTotalMoney=function(arr){
  14. var totalMoney=0;
  15. arr.reduce(function (preV, currV, currIndex, array){
  16. totalMoney+=base*(preV[1]+currV[1]);
  17. return currV;
  18. });//叠代算法:求零钱之和。
  19. return totalMoney;
  20. }
  21. //余额不足,没法找了
  22. var remain = getTotalMoney(cid);
  23. if (remain==change){//如果零钱数等于应找数额,返回closed
  24. return "Closed";
  25. }else if(remain < change){//没钱找了
  26. return "Insufficient Funds";
  27. };
  28. // 对应:1角-5角-1元-5元-10元-20元-50元-100元(以元为单位的基础上乘以面值基数:base这里为100)
  29. var dollar= [1, 5, 10, 25, 100, 500, 1000, 2000, 10000]; // TODO
  30. var pay={};//保存的key:dollar中面值索引,value:要找的此面值的个数
  31. var currLast=0;// 当前面值所剩余额
  32. var currMoney=0;//当前金钱面额(dollar中对应的值)
  33. for (var i=dollar.length-1;i>=0;i--){//由大到小循环
  34. //当前面值剩余金额
  35. currLast=cid[i][1]*base;
  36. if (currLast<=0) {
  37. continue;//当前面值的金额剩余0,跳过
  38. }
  39. //当前金额面值
  40. currMoney=dollar[i];
  41. // 在当前面值下取钱必须同时满足两个条件:
  42. // 1. 找零必须大于当前面值,比如找零51元,才可以从50里面取钱。
  43. // 2. 剩余的当前面值的总额足够,比如找4元,但我只有3张1元,就不符合取钱条件
  44. if(change>currMoney){//如果当前金额面值小于应找钱数
  45. if(change<currLast){
  46. // 找零小于当前面值剩余金额:比如找钱51元,当前50面值总额余额还有150元。
  47. pay[i]=Math.floor(change/currMoney);//取最大张数
  48. change-=currMoney*pay[i];//取完之后从应找余额中减去(张数x面值)
  49. }else{
  50. // 找零大于当前面值剩余金额,比如找零51元,我50元面额总值只有50元
  51. // 则将所有剩余金额找出
  52. pay[i]=Math.floor(currLast/currMoney);
  53. change-=currLast;//就直接减去当前面值剩余所有金额
  54. }
  55. }
  56. }//循环结束之后得到一个pay对象,里面包括了面值和对应应找的钱。
  57. console.log(pay)
  58. var res=[];
  59. // 组织最后需要找零的钱,作为最终返回的数组。
  60. var keys=Object.keys(pay);//找到pay对象
  61. var idx=0;
  62. var total=0;//应找零钱(pay)的总额
  63. for (var j=0; j<keys.length; j++) {
  64. // 需要找零的面值索引:比如100,50,20,10...等等
  65. idx=parseInt([keys[j]]);
  66. //计算该面值最后找出的零钱(公式:面值x需要找出数量 / 金钱面值基数)
  67. cid[idx][1]=dollar[idx]*pay[keys[j]]/base;
  68. res.unshift(cid[idx]);//把结果添加到数组的开头。符合由面值大到小的规律。
  69. total += dollar[idx]*pay[keys[j]];
  70. // 顺便计算下这里计算的结果应该和最开始需要找零的金额一致:
  71. // 面值x需要找出数量——返回到total结果中
  72. }
  73. // 找到最后,所有能找的面值加起来还不够
  74. // 这里与最开始不同,这里是过滤掉了所有找不开的面值
  75. // 比如:要找0.05元,但是目前剩余一张0.01和1元的面值,依旧判定为找不开
  76. // 而最开始的是所有余额加起来都不够找
  77. if (total<change) {
  78. return "Insufficient Funds";
  79. }
  80. console.log(res)
  81. return res;
  82. }
  83. // Example cash-in-drawer array:
  84. // [["PENNY", 1.01],
  85. // ["NICKEL", 2.05],
  86. // ["DIME", 3.10],
  87. // ["QUARTER", 4.25],
  88. // ["ONE", 90.00],
  89. // ["FIVE", 55.00],
  90. // ["TEN", 20.00],
  91. // ["TWENTY", 60.00],
  92. // ["ONE HUNDRED", 100.00]]
  93. checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]);

4.依照一个存着新进货物的二维数组,更新存着现有库存(在 arr1 中)的二维数组. 如果货物已存在则更新数量 . 如果没有对应货物则把其加入到数组中,更新最新的数量. 返回当前的库存数组,且按货物名称的字母顺序排列.

  1. unction updateInventory(arr1, arr2) {
  2. // All inventory must be accounted for or you're fired!
  3. return arr1;
  4. }
  5. // Example inventory lists
  6. var curInv = [
  7. [21, "Bowling Ball"],
  8. [2, "Dirty Sock"],
  9. [1, "Hair Pin"],
  10. [5, "Microphone"]
  11. ];
  12. var newInv = [
  13. [2, "Hair Pin"],
  14. [3, "Half-Eaten Apple"],
  15. [67, "Bowling Ball"],
  16. [7, "Toothpaste"]
  17. ];
  18. updateInventory(curInv, newInv);

思路好像不复杂,

(1)对两个数组构建对象。然后用hasOwnProperty判断有,则累加,没有则定义这个属性并给他赋值。

(2)获取对象的属性名并排序:Object.keys(obj).sort(),返回的是一个数组。再重新定义这个数组并输出。

  1. function updateInventory(arr1, arr2) {
  2. var oCur={};
  3. var oNew={};
  4. function arrToObj(arr,obj){
  5. for(var i=0;i<arr.length;i++){
  6. obj[arr[i][1]]=arr[i][0];
  7. }
  8. }//构造库存对象。
  9. arrToObj(arr1,oCur);
  10. arrToObj(arr2,oNew);
  11. //添加货物及属性
  12. for(i in oNew){
  13. console.log(oCur.hasOwnProperty(i))
  14. if(oCur.hasOwnProperty(i)){
  15. oCur[i]+=oNew[i];
  16. }else{
  17. oCur[i]=oNew[i];
  18. }
  19. }
  20. //属性名排序
  21. function objKeySort(obj) {//排序的函数
  22. var newkey = Object.keys(obj).sort();
  23.   //newkey是一个排序后的属性名数组
  24. var newObj = {};
  25. for (var i = 0; i < newkey.length; i++) {
  26. newObj[newkey[i]] = obj[newkey[i]];
  27. }
  28. return newObj;//返回排好序的新对象
  29. }
  30. oCur=objKeySort(oCur);
  31. //反向编译这个对象,然后返回成最初的数组。
  32. var newArr=[]
  33. for(i in oCur){
  34. newArr.push([oCur[i],i])
  35. }
  36. console.log(newArr);
  37. return newArr;
  38. }

5. 把一个字符串中的字符重新排列生成新的字符串,返回新生成的字符串里没有连续重复字符的字符串个数.连续重复只以单个字符为准

例如, aab 应该返回 2 因为它总共有6中排列 (aab, aab, aba, aba, baa, baa), 但是只有两个 (aba and aba)没有连续重复的字符 (在本例中是 a).

尝试过两个排列组合的算法,但是只有这个能验证通过。

  1. function permAlone(str) {
  2. //创建正则
  3. var regex = /(.)\1+/g;
  4. // 转化数组
  5. var arr = str.split('');
  6. var permutations = [];
  7. var tmp;
  8. //全部相等时返回0,否则再判断没意义。
  9. if (str.match(regex) !== null && str.match(regex)[0] === str) return 0;
  10. // 创建一个swap函数来交换变量的内容。
  11. function swap(index1, index2) {
  12. tmp = arr[index1];
  13. arr[index1]=arr[index2];
  14. arr[index2]=tmp;
  15. }//简单地说是:ab,ba
  16. //使用该函数算法生成数组排列。
  17. function generate(int) {
  18. if(int === 1){//如果数组内只有一个数据,换言之只有单个字母,直接返回原数组。
  19. //确保加入我们创建的字符排列是个数组
  20. permutations.push(arr.join(''));
  21. }else{
  22. for (var i=0; i<int;i++){
  23. generate(int-1);//自身调用,简而言之就是把后边自身的全排列好。
  24. swap(int % 2? 0 : i, int - 1);//偶数取0,否则取i
  25. }
  26. }
  27. }
  28. generate(arr.length);
  29. //过滤重复排列的数组。
  30. var filtered = permutations.filter(function(string) {
  31. return !string.match(regex);
  32. });
  33. //统计变量
  34. return filtered.length;
  35. }
  36. permAlone('abfdefa');

6.让日期区间更友好!

把常见的日期格式如:YYYY-MM-DD 转换成一种更易读的格式。

易读格式应该是用月份名称代替月份数字,用序数词代替数字来表示天 (1st 代替 1).

记住不要显示那些可以被推测出来的信息: 如果一个日期区间里结束日期与开始日期相差小于一年,则结束日期就不用写年份了。月份开始和结束日期如果在同一个月,则结束日期月份就不用写了。

另外, 如果开始日期年份是当前年份,且结束日期与开始日期小于一年,则开始日期的年份也不用写。

只能说它这个规则设置是非常非常坑爹的。

makeFriendlyDates(["2016-07-01", "2016-07-04"]) should return ["July 1st","4th"].

makeFriendlyDates(["2016-12-01", "2017-02-03"]) should return ["December 1st","February 3rd"].

makeFriendlyDates(["2016-12-01", "2018-02-03"]) should return ["December 1st, 2016","February 3rd, 2018"].

makeFriendlyDates(["2017-03-01", "2017-05-05"]) should return ["March 1st, 2017","May 5th"]

makeFriendlyDates(["2018-01-13", "2018-01-13"]) should return ["January 13th, 2018"].

makeFriendlyDates(["2022-09-05", "2023-09-04"]) should return ["September 5th, 2022","September 4th"].

makeFriendlyDates(["2022-09-05", "2023-09-05"]) should return ["September 5th, 2022","September 5th, 2023"].

  1. function makeFriendlyDates(arr) {
  2. //定义两个对象,一个存放参数1,一个存放参数2
  3. var oDate1={},oDate2={};
  4. var reArr=[];
  5. for(var i=0;i<arr.length;i++){
  6. reArr[i]=arr[i].split('-');
  7. if(i==0){
  8. oDate1["year"]=reArr[i][0];
  9. oDate1["month"]=reArr[i][1];
  10. oDate1["day"]=reArr[i][2];
  11. }else{
  12. oDate2["year"]=reArr[i][0];
  13. oDate2["month"]=reArr[i][1];
  14. oDate2["day"]=reArr[i][2];
  15. }
  16. }//通过这段程序把两个日期参数转化为两个json对象。格式为{"year":xxxx,"month:xx","day":xxx}(xxx全为数字)
  17. //因为上面的json还不足以满足格式,所以还得写个json,再写个函数转化这两个json。
  18. var oMonth={
  19. "01":"January",
  20. "02":"February",
  21. "03":"March",
  22. "04":"April",
  23. "05":"May",
  24. "06":"June",
  25. "07":"July",
  26. "08":"August",
  27. "09":"September",
  28. "10":"October",
  29. "11":"November",
  30. "12":"December"
  31. };//定义月份对象
  32. function getFunDay(obj){
  33. //判断日期:
  34. switch(obj["day"]){
  35. case "01":
  36. obj["day"]="1st";
  37. break;
  38. case "02":
  39. obj["day"]="2nd";
  40. break;
  41. case "03":
  42. obj["day"]="3rd";
  43. break;
  44. case "04":
  45. case "05":
  46. case "06":
  47. case "07":
  48. case "08":
  49. case "09":
  50. obj["day"]=obj["day"][1]+"th";
  51. break;
  52. case "21":
  53. obj["day"]+='st';
  54. break;
  55. case "22":
  56. obj["day"]+='nd';
  57. break;
  58. case "23":
  59. obj["day"]+='rd';
  60. break;
  61. default:
  62. obj["day"]+='th';
  63. }
  64. //判断月份
  65. for(i in oMonth){
  66. if(obj["month"]==i){
  67. obj["month"]=oMonth[i];
  68. }
  69. }
  70. }
  71. getFunDay(oDate1);
  72. getFunDay(oDate2);
  73. //console.log(oDate1);
  74. //转化之后这两个对象的格式就正确了。
  75. //接下来是一段非常繁琐的判断流程,如果是新手,建议画出流程图来做
  76. if(oDate1["year"]==oDate2["year"]){//是否同年
  77. if(oDate1["month"]==oDate2["month"]){//是否同年同月
  78. if(oDate1["day"]==oDate2["day"]){//是否同年同月同日
  79. console.log([[oDate1["month"],oDate1["day"]+",",oDate1["year"]].join(' ')])//注意,同年同月同日的话,这里有个全直接输出口。
  80. return [[oDate1["month"],oDate1["day"]+",",oDate1["year"]].join(' ')];
  81. }else{//同年同月不同日
  82. delete oDate1["year"];
  83. delete oDate2["year"];
  84. delete oDate2["month"];
  85. }
  86. }else{ //同年不同月
  87. delete oDate2["year"];
  88. }
  89. }else if((Math.abs(oDate1["year"]-oDate2["year"])==1)){//不同年,年份但只差一年
  90. if(oDate1["month"]<oDate2["month"]){//如果在一年以内
  91. delete oDate1["year"];
  92. delete oDate2["year"];
  93. }else if(oDate1["month"]==oDate2["month"]){//差一年同月
  94. if(oDate1["day"]>oDate2["day"]){ //小于一年
  95. delete oDate2["year"];
  96. }
  97. }
  98. }
  99. //以下定义输出函数。把json数据转化为一个字符串。
  100. //默认的输出格式里,日期是带逗号的,但经过上面一轮判断,日期可能变成字符串的最后一个。在带逗号就不对了。所以需要判断字符串
  101. function retArr(obj1,obj2){
  102. var returnArr=[];
  103. //先按输出规则构造一个数组
  104. //这些规则可能调用了已被删除的属性。对应为undefined。所以过滤掉。
  105. var objstr1=[obj1["month"],obj1["day"]+",",obj1["year"]].filter(function(a){return a!=undefined}).join(' ');
  106. var objstr2=[obj2["month"],obj2["day"]+",",obj2["year"]].filter(function(a){return a!=undefined}).join(' ');
  107. //
  108. if(objstr1.substring(objstr1.length-1)==','){
  109. objstr1=objstr1.replace(objstr1.substring(objstr1.length-1),'')
  110. }
  111. if(objstr2.substring(objstr2.length-1)==','){
  112. console.log(objstr1.substring(objstr1.length-1))
  113. objstr2=objstr2.replace(objstr2.substring(objstr2.length-1),'')
  114. }
  115. returnArr=[objstr1,objstr2];
  116. return returnArr;
  117. }
  118. console.log(retArr(oDate1,oDate2));
  119. return retArr(oDate1,oDate2);
  120. }
  121. makeFriendlyDates(["2016-07-01", "2016-07-04"]);
  122. //makeFriendlyDates(["2016-12-01", "2017-02-03"]);
  123. //makeFriendlyDates(["2016-12-01", "2018-02-03"]);
  124. //makeFriendlyDates(["2017-03-01", "2017-05-05"]);
  125. //makeFriendlyDates(["2018-01-13", "2018-01-13"]);
  126. //makeFriendlyDates(["2022-09-05", "2023-09-04"]);
  127. //makeFriendlyDates(["2022-09-05", "2023-09-05"])

7.用下面给定的方法构造一个对象.

方法有 getFirstName(), getLastName(), getFullName(), setFirstName(first), setLastName(last), and setFullName(firstAndLast).

所有有参数的方法只接受一个字符串参数.

所有的方法只与实体对象交互.

思路,好像没什么思路。

  1. function Person(fullName){
  2. this.getFirstName=function(){
  3. return fullName.split(' ')[0];
  4. };
  5. this.getLastName=function(){
  6. return fullName.split(' ')[1];
  7. };
  8. this.getFullName=function(){
  9. return fullName;
  10. };
  11. this.setFirstName=function(firstName){
  12. var arr=fullName.split(' ');
  13. arr.splice(0,1,firstName)
  14. fullName=arr.join(' ');
  15. };
  16. this.setLastName=function(lastName){
  17. var arr=fullName.split(' ');
  18. arr.splice(1,1,lastName);
  19. fullName=arr.join(' ');
  20. };
  21. this.setFullName=function(name){
  22. fullName=name;
  23. };
  24. }

注意set首名和尾名不能采用链式写法。

8.返回一个数组,其内容是把原数组中对应元素的平均海拔转换成其对应的轨道周期.

原数组中会包含格式化的对象内容,像这样 {name: 'name', avgAlt: avgAlt}.

至于轨道周期怎么求,戳这里 on wikipedia (不想看英文的话可以自行搜索以轨道高度计算轨道周期的公式).

求得的值应该是一个与其最接近的整数,轨道是以地球为基准的.

地球半径是 6367.4447 kilometers, 地球的GM值是 398600.4418, 圆周率为Math.PI

orbitalPeriod([{name : "sputnik", avgAlt : 35873.5553}]) 应该返回 [{name: "sputnik", orbitalPeriod: 86400}].

orbitalPeriod([{name: "iss", avgAlt: 413.6}, {name: "hubble", avgAlt: 556.7}, {name: "moon", avgAlt: 378632.553}]) 应该返回 [{name : "iss", orbitalPeriod: 5557}, {name: "hubble", orbitalPeriod: 5734}, {name: "moon", orbitalPeriod: 2377399}].

  1. function orbitalPeriod(arr) {
  2. var GM = 398600.4418;
  3. var earthRadius = 6367.4447;
  4. return arr;
  5. }
  6. orbitalPeriod([{name : "sputnik", avgAlt : 35873.5553}]);

在此需要补下高一物理的课。以万有引力做向心力,则GMm/R2=mrω2 ω=2π/T,R=r+h,所以T=2π(r+h)·sqr((r+h)/GM)。

  1. function orbitalPeriod(arr) {
  2. var GM = 398600.4418;
  3. var earthRadius = 6367.4447;
  4. for(var i=0;i<arr.length;i++){
  5. var R=(arr[i].avgAlt+6367.4447);
  6. var T=R*2*Math.PI*Math.sqrt((R/GM));
  7. delete arr[i].avgAlt;
  8. arr[i].orbitalPeriod=Math.round(T);
  9. }
  10. console.log(arr)
  11. return arr;
  12. }

好像也没什么思路可说的。

9.找到你的另一半

举个例子:有一个能力数组[7,9,11,13,15],按照最佳组合值为20来计算,只有7+13和9+11两种组合。而7在数组的索引为0,13在数组的索引为3,9在数组的索引为1,11在数组的索引为2。

所以我们说函数:pairwise([7,9,11,13,15],20) 的返回值应该是0+3+1+2的和,即6。

我们可以通过表格来更直观地查看数组中索引和值的关系:

| Index | 0 | 1 | 2 | 3 | 4 |

| Value | 7 | 9 | 11 | 13 | 15 |

任务:帮右边的pairwise函数实现上面的功能。

思路,原题意思是匹配了一次之后数组项就不能再用了。那就把它设为false吧。

  1. function pairwise(arr, arg) {
  2. var arr2=arr;
  3. var count=0;
  4. for(var j=0;j<arr.length;j++){
  5. for(var i=j+1;i<arr2.length;i++){
  6. if(arr[j]+arr2[i]==arg){
  7. count+=i+j;
  8. arr[i]="false";
  9. arr[j]="false"
  10. }
  11. }
  12. }
  13. console.log(count)
  14. return count;
  15. }

题目来源:

FCC中文网:https://www.freecodecamp.cn/

参考资料:

[1]《javascript高级程设计》第3,5,6,7章。 (就做题查阅学习而言,这本书确实无愧于“红宝书”)

[2] MOZILLA开发者社区:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript 

[3] 感谢gitter中文聊天室热心的网友

fcc的高级算法题的更多相关文章

  1. fcc的中级算法题

    核心提示:这是网上开源编程学习项目FCC的javascript中级编程题(Intermediate Algorithm Scripting(50 hours)),一共20题.建议时间是50个小时,对于 ...

  2. FCC JS基础算法题(5):Return Largest Numbers in Arrays(找出多个数组中的最大数)

    题目描述: 找出多个数组中的最大数右边大数组中包含了4个小数组,分别找到每个小数组中的最大值,然后把它们串联起来,形成一个新数组.提示:你可以用for循环来迭代数组,并通过arr[i]的方式来访问数组 ...

  3. FCC JS基础算法题(4):Title Case a Sentence(句中单词首字母大写)

    题目描述: 确保字符串的每个单词首字母都大写,其余部分小写.像'the'和'of'这样的连接符同理. 算法: function titleCase(str) { // 转小写及分割成数组 var st ...

  4. FCC JS基础算法题(2):Check for Palindromes(检查回文字符串)

    题目描述: 如果给定的字符串是回文,返回true,反之,返回false.如果一个字符串忽略标点符号.大小写和空格,正着读和反着读一模一样,那么这个字符串就是palindrome(回文).注意你需要去掉 ...

  5. FCC JS基础算法题(1):Factorialize a Number(计算一个整数的阶乘)

    题目描述: 如果用字母n来代表一个整数,阶乘代表着所有小于或等于n的整数的乘积.阶乘通常简写成 n!例如: 5! = 1 * 2 * 3 * 4 * 5 = 120. 算法: function fac ...

  6. FCC JS基础算法题(0):Reverse a String(翻转字符串)

    题目描述: 先把字符串转化成数组,再借助数组的reverse方法翻转数组顺序,最后把数组转化成字符串.你的结果必须得是一个字符串. 算法: function reverseString(str) { ...

  7. FCC JS基础算法题(10):Falsy Bouncer(过滤数组假值)

    题目描述: 删除数组中的所有假值.在JavaScript中,假值有false.null.0."".undefined 和 NaN. 使用filter方法,过滤掉生成的 Boolea ...

  8. FCC JS基础算法题(3):Find the Longest Word in a String (找出最长单词)

    题目描述: 在句子中找出最长的单词,并返回它的长度.函数的返回值应该是一个数字. 基本思路,将字符串转换成数组,然后得出数组中单个元素的长度,对长度进行排序,返回最大的一个 代码: function ...

  9. FCC JS基础算法题(13):Caesars Cipher(凯撒密码)

    题目描述: 下面我们来介绍风靡全球的凯撒密码Caesar cipher,又叫移位密码.移位密码也就是密码中的字母会按照指定的数量来做移位.一个常见的案例就是ROT13密码,字母会移位13个位置.由'A ...

随机推荐

  1. JSON与js对象序列化

    JavaScript对象表示法(JavaScript Object Notation,简称JSON)是一种轻量级的数据交换格式,它基于js字面量表示法,是js的一个子集.虽然是一个js的子集但是他与语 ...

  2. ES6 变量的解构赋值

    数组的解构赋值     var [a,b,c] = [1,2,3];    左边是变量,右边是值,根据数据结构一一对应 只要等号两边的模式相同,左边的变量就会被赋予右边对应的值,必须模式相同 如果等号 ...

  3. url中#号的作用

    url中#号的作用就是本页面位置跳转 比如这个url地址:http://www.aaaaa.com/index.html?ad=34&m=c#red red就是index.html页面的依哥位 ...

  4. 【转】在mac上配置安卓SDK

    众所周知的原因,google的很多网站在国内无法访问,苦逼了一堆天朝程序员,下是在mac本上折腾android 开发环境的过程: 一.先下载android sdk for mac 给二个靠谱的网址: ...

  5. Linux下的IO模式

    对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间.所以说,当一个read操作发生时,它会经历两个阶段:1. 等待数据准 ...

  6. Angular实现注册系统

    Angular是Google开发的前端技术框架,下载地址:https://code.angularjs.org/1.5.0/angular.js 通过对angular的简单理解后发现,angular通 ...

  7. Leetcode 226. Invert Binary Tree

    Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 class Solution(object): ...

  8. Jenkins的Publish Over FTP Plugin插件参数使用

    无论在Windows还是Linux下,都是采用这样方式${WORKSPACE}

  9. FIneCMS /dayrui/libraries/Chart/ofc_upload_image.php Arbitrary File Upload Vul

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Relevant Link: http://www.wooyun.org ...

  10. Allegro笔记三

    1.设置Gerber导出目录 可以在$Install_Dir/share/pcb/text/env.txt目录里面添加:“set artpath = . ../Gerber/”语句. 其他各种文件夹设 ...