JavaScript專項算法題(2):函數式編程

@冒泡的馬樹javascript

題庫原地址:http://csbin.io/functionaljava

高階函數

挑戰1

問題:算法

構建一個addTwo函數,做用爲接受一個參數並將參數加2。api

題解:數組

// Challenge 1
const addTwo = (num) => {
    return num + 2;
};

// To check if you've completed this function, uncomment these console.logs!
console.log(addTwo(3));
console.log(addTwo(10));

挑戰2

問題:閉包

構建一個addS函數,做用爲接受一個參數並將參數與「s"拼接。ide

題解:函數

// Challenge 2
const addS = (word) => {
    return word.toString() + 's';
};

// Uncomment these to check your work
console.log(addS('pizza'));
console.log(addS('bagel'));

挑戰3

問題:測試

構建一個map函數,其接受兩個參數:this

  1. 數值型數組
  2. 回調函數——一個應用於上述數值型數組中的每個元素的函數(於map函數內)

map函數的返回值爲包含上述數值型數組元素逐個運行回調函數後生成的元素值的新數組。

map([1,2,3,4,5], multiplyByTwo); //-> [2,4,6,8,10]
multiplyByTwo(1); //-> 2
multiplyByTwo(2); //-> 4

題解:

// Challenge 3
const map = (array, callback) => {
    const newArray = [];
  for(let i = 0; i< array.length; i++){
    newArray.push(callback(array[i]));
  }
  return newArray;
};

console.log(map([1, 2, 3], addTwo));

挑戰4

問題:

函數forEach接受一個數組和一個回調函數,運行回調函數於輸入數組的每個元素。forEach函數無返回值。

let alphabet = '';
const letters = ['a', 'b', 'c', 'd'];
forEach(letters, char => alphabet += char);
console.log(alphabet);   //prints 'abcd'

題解:

// Challenge 4
const forEach = (array, callback) => {
    for(let i = 0; i<array.length; i++){
    callback(array[i]);
  }
};

// See for yourself if your forEach works!
let alphabet = '';
const letters = ['a', 'b', 'c', 'd'];
forEach(letters, char => alphabet += char);
console.log(alphabet);   //prints 'abcd'

挑戰5

問題:

在這個挑戰中,你須要將map函數重構爲mapWith。這一次你要在mapWith中使用forEach函數而不是使用for循環。

題解:

// Challenge 5
const mapWith = (array, callback) => {
    const newArray = new Array;
  forEach(array, el => newArray.push(callback(el)));
  return newArray;
};
console.log(mapWith([1, 2, 3], addTwo));

挑戰6

問題:

函數reduce接受一個數組並將數組內的全部值合併爲一個值。好比,它能夠將數組求和,求積,以及其它你想加進函數中的操做。

const nums = [4, 1, 3];
const add = (a, b) => a + b; 
reduce(nums, add, 0);   //-> 8

如下是它的運行原理。函數有一個「累加器值」(第三個參數),做用爲充當初始值而且累加每一次循環的輸出值。數組參數會被遍歷,傳遞「累加器值「和新的數組元素值做爲參數到回調函數中。回調函數的返回值會成爲新的」累加器值「。下一個循環會使用這個新」累加器值「。在上面的例子中,」累加器值「剛開始爲0,調用add(0, 4),」累加器值「變爲4,而後add(4, 1)將其變爲5,最後add(5, 3)獲得8並最終返回。

題解:

// Challenge 6
const reduce = (array, callback, initialValue) => {
    let newValue = initialValue;
    for(let i = 0; i<array.length; i++){
    newValue = callback(newValue, array[i]);
  }
  return newValue;
};

const nums = [4, 1, 3];
const add = (a, b) => a + b; 
console.log(reduce(nums, add, 0));   //-> 8

挑戰7

問題:

構建intersection函數,做用爲比較輸入進來的多組數組並返回一個包含數組間共同元素的新數組。獎勵:使用reduce!

題解:

// Challenge 7
const intersection = (arrays) => {
  return arrays.reduce((acc, curr) => {
    return curr.filter(el => acc.includes(el));
  })
};

console.log(intersection([[5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]]));
// should log: [5, 15]

挑戰8 

問題:

構建union函數,做用爲比較輸入進來的多組數組並返回一個包含輸入數組中全部元素的新數組。若是存在重複元素,則新數組中僅保留一個,另外需保留新數組的元素順序爲從第一個輸入數組的第一個元素開始。獎勵:使用reduce!

題解:

// Challenge 8
const union = (arrays) => {
    return arrays.reduce((acc, curr) => {
    // acc.push(curr.filter(el => !acc.includes(el)));
    return acc.concat(curr.filter(el => !acc.includes(el)));
  })
};

console.log(union([[5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]]));
// should log: [5, 10, 15, 88, 1, 7, 100]

挑戰9

問題:

構建objOfMatches函數,接受兩個數組和一個回調函數做爲參數,做用爲建立一個特定對象並返回。objOfMatches會使用回調函數測試第一個數組的每個元素以確認其輸出是否匹配於第二個數組內相同下標的元素。若是匹配,第一個數組內的這個元素會成爲所建立對象的鍵,而第二個數組內的相同下標元素則會成爲對應的值。

題解:

// Challenge 9
const objOfMatches = (array1, array2, callback) => {
    const matchObj = {};
  for(let i =0; i<array1.length; i++){
    if(callback(array1[i])===array2[i]){
      matchObj[array1[i]] = array2[i];
    }
  }
  return matchObj;
};

console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], (str) => str.toUpperCase()));
// should log: { hi: 'HI', bye: 'BYE', later: 'LATER' }

挑戰10

問題:

構建multiMap函數,接受兩個數組做爲參數,第一個數組的元素爲值而第二個數組的元素爲回調函數。multiMap會返回一個特定對象,該對象的鍵爲第一個數組的值,鍵對應的值則是將鍵依序傳入第二個數組的回調函數中獲得的返回值組成的新數組。

題解:

// Challenge 10
const multiMap = (arrVals, arrCallbacks) => {
    const multiMapObj = {};
  let tempArray = [];
  arrVals.forEach(el => {
    tempArray = [];
    for(let i=0; i<arrCallbacks.length; i++){
      tempArray.push(arrCallbacks[i](el));
    }
    multiMapObj[el] = tempArray;
  })
  return multiMapObj;
};

console.log(multiMap(['catfood', 'glue', 'beer'], [(str) => str.toUpperCase(), (str) => str[0].toUpperCase() + str.slice(1).toLowerCase(), (str) => str + str]));
// should log: { catfood: ['CATFOOD', 'Catfood', 'catfoodcatfood'], glue: ['GLUE', 'Glue', 'glueglue'], beer: ['BEER', 'Beer', 'beerbeer'] }

挑戰11

問題:

構建commutative函數,接受參數爲兩個回調函數和一個值。commutative會返回一個布爾值,從而代表運行第一個回調函數於輸入值,再將獲得的返回值輸入到第二個回調函數中運行,獲得的結果與逆序操做是否相同(即運行輸入值於第二個回調函數,獲得的返回值再輸入到第一個回調函數中)。

題解:

// Challenge 11
const commutative = (func1, func2, value) => {
    if(func1(func2(value)) === func2(func1(value))){
    return true;
  } else {
    return false;
  }
};

/*** Uncomment these to check your work! ***/
const multBy3 = n => n * 3;
const divBy4 = n => n / 4;
const subtract5 = n => n - 5;
console.log(commutative(multBy3, divBy4, 11)); // should log: true
console.log(commutative(multBy3, subtract5, 10)); // should log: false
console.log(commutative(divBy4, subtract5, 48)); // should log: false

挑戰12

問題:

構建objectFilter函數,第一個參數爲對象,第二個參數爲回調函數。objectFilter函數會返回特定對象。此特定對象所包含的屬性爲輸入對象中值與其對應鍵傳入回調函數獲得的返回值一致的鍵值對。

題解:

// Challenge 12
const objFilter = (obj, callback) => {
    const objectFilterObj = {};
  for(let key in obj) {
    if(obj[key] === callback(key)){
      objectFilterObj[key] = obj[key];
    }
  }
  return objectFilterObj;
};

/*** Uncomment these to check your work! ***/
const startingObj = {};
startingObj[6] = 3;
startingObj[2] = 1;
startingObj[12] = 4;
const half = n => n / 2;
console.log(objFilter(startingObj, half)); // should log: { 2: 1, 6: 3 }

挑戰13

問題:

構建rating函數,接受參數爲一個由函數組成的數組和一個值。數組中的函數的返回值皆爲true或false。rating會返回一個代表將輸入值運行於數組中的函數會返回true的百分比數。

題解:

// Challenge 13
const rating = (arrOfFuncs, value) => {
    let trueCounter = 0; 
    arrOfFuncs.forEach(el => {
    if(el(value)){
       trueCounter++;
      }
  })
  return trueCounter/arrOfFuncs.length * 100;
};

/*** Uncomment these to check your work! ***/
const isEven = n => n % 2 === 0;
const greaterThanFour = n => n > 4;
const isSquare = n => Math.sqrt(n) % 1 === 0;
const hasSix = n => n.toString().includes('6');
const checks = [isEven, greaterThanFour, isSquare, hasSix];
console.log(rating(checks, 64)); // should log: 100
console.log(rating(checks, 66)); // should log: 75

挑戰14

問題:

構建pipe函數,接受參數爲一個由函數組成的數組和一個值。pipe會將輸入值輸入到數組的第一個函數中,而後再將獲得的輸出值輸入到第二個函數中,而後輸出值又再輸入到第三個函數中,一直下去,直到獲得數組的最後一個函數的輸出值。pipe會返回這個最終輸出值。

題解:

// Challenge 14
const pipe = (arrOfFuncs, value) => {
    let output = value;
    arrOfFuncs.forEach(el => {
    output = el(output);
  })
  return output;
};

/*** Uncomment these to check your work! ***/
const capitalize = str => str.toUpperCase();
const addLowerCase = str => str + str.toLowerCase();
const repeat = str => str + str;
const capAddlowRepeat = [capitalize, addLowerCase, repeat];
console.log(pipe(capAddlowRepeat, 'cat')); // should log: 'CATcatCATcat'

挑戰15

問題:

構建highestFunc函數,接受參數爲一個對象(包含函數)和一個值。highestFunc會返回輸入對象中運行輸入值後獲得最高值的函數所對應的鍵。

題解:

// Challenge 15
const highestFunc = (objOfFuncs, subject) => {
    let maxKey = "";
  let maxNumber = Number.NEGATIVE_INFINITY;
  for(let key in objOfFuncs) {
    if(objOfFuncs[key](subject) > maxNumber){
      maxNumber = objOfFuncs[key](subject);
      maxKey = key;
    }
  }
  return maxKey;
};

/*** Uncomment these to check your work! ***/
const groupOfFuncs = {};
groupOfFuncs.double = n => n * 2;
groupOfFuncs.addTen = n => n + 10;
groupOfFuncs.inverse = n => n * -1;
console.log(highestFunc(groupOfFuncs, 5)); // should log: 'addTen'
console.log(highestFunc(groupOfFuncs, 11)); // should log: 'double'
console.log(highestFunc(groupOfFuncs, -20)); // should log: 'inverse'

閉包

挑戰1

問題:

構建createFunction函數,用於建立和返回函數。當被建立的函數被調用時,它會打印「hello"。

const function1 = createFunction();
// now we'll call the function we just created
function1(); //should console.log('hello');

題解:

// Challenge 1
const createFunction = () => {
    const innerFunction = () => {
    console.log('hello');
    }
    return innerFunction;
};

// UNCOMMENT THESE TO TEST YOUR WORK!
const function1 = createFunction();
function1();

挑戰2

問題:

構建接受一個輸入值做爲參數的createFunctionPrinter函數,用於建立和返回一個特定函數。當特定函數被調用時,其應該打印特定函數被建立時輸入createFunctionPrinter中的值。

const printSample = createFunctionPrinter('sample');
const printHello = createFunctionPrinter('hello')
// now we'll call the functions we just created
printSample(); //should console.log('sample');
printHello(); //should console.log('hello');

題解:

// Challenge 2
const createFunctionPrinter = (input) => {
  let inputValue = input;
    const innerFunction = (inputValue) => {
    console.log(input);
  }
  return innerFunction;
};

// UNCOMMENT THESE TO TEST YOUR WORK!
const printSample = createFunctionPrinter('sample');
printSample();
const printHello = createFunctionPrinter('hello');
printHello();

挑戰3

問題:

觀察下面outer函數的實現代碼。注意其會返回一個函數並且那個函數使用了不在其做用域的變量。嘗試推斷一下運行outer函數獲得的輸出值。

代碼:

// Challenge 3
const outer = () => {
  let counter = 0; // this variable is outside incrementCounter's scope
  const incrementCounter = () => {
    counter++;
    console.log('counter', counter);
  }
  return incrementCounter;
};

const willCounter = outer();
const jasCounter = outer();

// Uncomment each of these lines one by one.
// Before your do, guess what will be logged from each function call.

willCounter();
willCounter();
willCounter();

jasCounter();
willCounter();

挑戰4

問題:

構建addByX函數,其會返回一個接受一個輸入值做爲參數並與x相加的函數。

const addByTwo = addByX(2);
addByTwo(1); //should return 3
addByTwo(2); //should return 4
addByTwo(3); //should return 5

const addByThree = addByX(3);
addByThree(1); //should return 4
addByThree(2); //should return 5

const addByFour = addByX(4);
addByFour(4); //should return 8
addByFour(10); //should return 14

題解:

// Challenge 4
const addByX = (x) => {
    const outerInput = x;
  const innerFunction = (innerInput) => {
    return x + innerInput;
  }
  return innerFunction;
};

const addByTwo = addByX(2);

// now call addByTwo with an input of 1
console.log(addByTwo(1));

// now call addByTwo with an input of 2
console.log(addByTwo(2));

挑戰5

問題:

構建once函數,接受參數爲一個回調函數並返回一個特定函數。當特定函數被第一次調用時,其會調用回調函數並返回輸出值。若是其不是被第一次調用,則特定函數僅僅返回第一次調用時獲得的回調函數返回值,而不是再次運行回調函數。

題解:

// Challenge 5
const once = (func) => {
    let counter = 0;
  let onceResult = 0;
  const innerFunction = (el) => {
    counter++;
    if(counter === 1) {
      onceResult = func(el);
      return onceResult;
    } else{
      return onceResult;
    }
  }
  return innerFunction;
};

const onceFunc = once(addByTwo);

// UNCOMMENT THESE TO TEST YOUR WORK!
console.log(onceFunc(4));  //should log 6
console.log(onceFunc(10));  //should log 6
console.log(onceFunc(9001));  //should log 6

挑戰6

問題:

構建after函數,接受一個數字n和一個回調函數做爲參數。回調函數須要在經過after構建的函數運行第n次時才被運行。

題解:

// Challenge 6
const after = (count, func) => {
    let counter = count;
  const innerFunction = (el) => {
    if(--counter === 0){
      func(el);
    }
  }
  return innerFunction;
};

const called = () => console.log('hello');
const afterCalled = after(3, called);

afterCalled(); // -> nothing is printed
afterCalled(); // -> nothing is printed
afterCalled(); // -> 'hello' is printed

挑戰7

問題:

構建delay函數,做用爲接受一個回調函數做爲第一個參數,一個數值n(單位爲毫秒)做爲第二個參數,返回一個特定函數。delay構建的特定函數被調用後,須經n毫秒後才運行回調函數。任何其餘賦給特定函數的參數會在n毫秒後被回調函數使用。提示:研究setTimeout();

題解:

// Challenge 7
const delay = (func, wait) => {
  const waitTime = wait;
  const innerFunction = (el) => {
      setTimeout((el) => {
      func(el);
    }, waitTime);  
  }
    return innerFunction;
};

const delayCalled = delay(called, 2000);

delayCalled(); // "hello" after 2 seconds.

挑戰8

問題:

構建russianRoulette函數,做用爲接受一個數值參數(假設爲n)並返回一個特定函數。此特定函數不接受輸入參數,並且會在前n-1次調用時返回字符串「click「,在第n次調用時則返回字符串」bang「,n次之後再調用皆返回字符串」reload to play again"。

題解:

// Challenge 8
const russianRoulette = (num) => {
    let counter = num;
  const innerFunction = () => {
    counter--;
    if(counter>0) {
      return "click";
    } else if(counter==0){
      return "bang";
    } else{
      return "reload to play again";
    }
  }
  return innerFunction; 
};

/*** Uncomment these to check your work! ***/
const play = russianRoulette(3);
console.log(play()); // should log: 'click'
console.log(play()); // should log: 'click'
console.log(play()); // should log: 'bang'
console.log(play()); // should log: 'reload to play again'
console.log(play()); // should log: 'reload to play again'

// Challenge 8
const russianRoulette = (num) => {
    let counter = num;
  const innerFunction = () => {
    counter--;
    if(counter>0) {
      return "click";
    } else if(counter==0){
      return "bang";
    } else{
      return "reload to play again";
    }
  }
  return innerFunction; 
};

/*** Uncomment these to check your work! ***/
const play = russianRoulette(3);
console.log(play()); // should log: 'click'
console.log(play()); // should log: 'click'
console.log(play()); // should log: 'bang'
console.log(play()); // should log: 'reload to play again'
console.log(play()); // should log: 'reload to play again'

挑戰9

問題:

構建average函數,不接受參數,並返回一個特定函數(接受一個數值做爲參數或無參數)。當average建立的特定函數被輸入數值參數的方式調用時,返回值爲全部曾經被輸入到特定函數的數值參數的平均值(重複數值視爲分別的數值)。當特定函數被無參數的方式調用時,返回當前的平均值。若是特定函數在無參數方式調用時未曾被輸入數值參數的方式調用過,則返回0。

題解:

// Challenge 9
const average = () => {
    let averageValue = 0;
  let argumentCounter = 0;
  let argumentSum = 0;
  const innerFunction = (el) => {
    if(el == undefined) {
            return averageValue;
    } else{
      argumentCounter++;
      argumentSum += el; 
      averageValue = argumentSum / argumentCounter;
      return averageValue;
    }
  }
  return innerFunction;
};

/*** Uncomment these to check your work! ***/
const avgSoFar = average();
console.log(avgSoFar()); // should log: 0
console.log(avgSoFar(4)); // should log: 4
console.log(avgSoFar(8)); // should log: 6
console.log(avgSoFar()); // should log: 6
console.log(avgSoFar(12)); // should log: 8
console.log(avgSoFar()); // should log: 8

挑戰10

問題:

構建makeFuncTester函數,接受參數爲一個二維數組(其中第二維數組僅含兩個元素),返回一個接收回調函數做爲參數的特定函數。當二維數組的每個子數組的第一個元素輸入到回調函數時都產生與第二個元素相同的返回值時,特定函數返回ture,不然特定函數返回false。

題解:

// Challenge 10
const makeFuncTester = (arrOfTests) => {
  const firstLayerArray = [];
  for(let i = 0; i<arrOfTests.length; i++){
    let secondLayerArray = [];
    for(let j = 0; j<arrOfTests[i].length; j++){
      secondLayerArray.push(arrOfTests[i][j]);
    }
    firstLayerArray.push(secondLayerArray);
  }
  const innerFunction = (callback) => {
    for(let i=0; i<firstLayerArray.length; i++){
      if(callback(firstLayerArray[i][0]) !== firstLayerArray[i][1]){
        return false;
      }
    }
    return true;
  }
  return innerFunction;
};

/*** Uncomment these to check your work! ***/
const capLastTestCases = [];
capLastTestCases.push(['hello', 'hellO']);
capLastTestCases.push(['goodbye', 'goodbyE']);
capLastTestCases.push(['howdy', 'howdY']);
const shouldCapitalizeLast = makeFuncTester(capLastTestCases);
const capLastAttempt1 = str => str.toUpperCase();
const capLastAttempt2 = str => str.slice(0, -1) + str.slice(-1).toUpperCase();
console.log(shouldCapitalizeLast(capLastAttempt1)); // should log: false
console.log(shouldCapitalizeLast(capLastAttempt2)); // should log: true

挑戰11

問題:

構建makeHistory函數,接受一個數值參數n(充當限定值)並返回一個特定函數(接受字符串做爲參數)。特定函數會存儲限定個數爲n的最近輸入到此特定函數中的字符串參數歷史(每次調用存儲一次)。每次一個字符串被輸入到特定函數中,特定函數會返回拼接「done」於此字符串後的新字符串(空格做爲間隔)。然而,若是輸入字符串爲「undo」,特定函數會刪除字符串參數歷史中的最近字符串值,返回拼接「undone」於此最近字符串後的新字符串(空格做爲間隔)。若是輸入字符串「undo」時特定函數中的字符串參數歷史已爲空,那麼特定函數會返回字符串「nothing to undo」。

題解:

// Challenge 11
const makeHistory = (limit) => {
    const limitNumber = limit; 
  let parameterStack = [];
  const innerFunction = (stringElement) => {
    if(stringElement === "undo"){
      if(parameterStack.length == 0) {
        return "nothing to undo";
      } else{
        return `${parameterStack.pop()} undone`;
      }
    } else{
      parameterStack.push(stringElement);
      if(parameterStack.length > limit){
        parameterStack = parameterStack.slice(-limit);
      }
      return `${stringElement} done`;
    }
  }
  return innerFunction;
};

/*** Uncomment these to check your work! ***/
const myActions = makeHistory(2);
console.log(myActions('jump')); // should log: 'jump done'
console.log(myActions('undo')); // should log: 'jump undone'
console.log(myActions('walk')); // should log: 'walk done'
console.log(myActions('code')); // should log: 'code done'
console.log(myActions('pose')); // should log: 'pose done'
console.log(myActions('undo')); // should log: 'pose undone'
console.log(myActions('undo')); // should log: 'code undone'
console.log(myActions('undo')); // should log: 'nothing to undo'

挑戰12

問題:

仔細觀察測試代碼若是你須要幫忙來理解下面的算法描述。

構建blackjack函數,接受參數爲一個數組(元素皆爲從1到11的數值),返回一個DEALER函數。 DEALER函數會接受兩個參數(皆爲數值),而後返回一個另外的PLAYER函數。

在第一次調用PLAYER函數時,它會返回輸入DEALER函數中的兩個數值參數之和。

在第二次調用PLAYER函數時,它會返回下列兩種狀況中的一種:

  1. 輸入blackjack函數的數值型數組的第一個數值加上輸入DEALER函數中的兩個數值參數之和獲得的和,若是和小於等於21,返回此和;
  2. 若是和大於21,返回字符串「bust」。

若是第二次調用PLAYER函數時已返回"bust",則接下來PLAYER函數的每次調用皆會返回字符串「you are done!"(不過不一樣於「bust",輸出」you are done!「時不會使用數值型數組中的數值)。若是第二次調用PLAYER函數時並未返回」bust「,則接下來調用PLAYER函數時會返回下列兩種狀況中的一種:

  1. 最近一次的和值加上數值型數組的下一個數值元素,若是這個求和結果小於等於21的話,返回此和;
  2. 返回「bust」若是求和結果大於21。

再次聲明,若是其返回"bust",則接下來PLAYER函數的每次調用皆會返回字符串「you are done!",不然,PLAYER函數會繼續使用最近一次和值與數值型數組的下一個數值元素求和,一直下去。

你能夠假設給定的數值型數組有足夠多的數值元素從而會在用完數組元素以前獲得「bust"。

題解:

// Challenge 12
const blackjack = (array) => {
    const dealer = (num1, num2) => {
    let first = true;
    let bust = false; 
    let sum = num1 + num2; 
    const player = () => {
      if(first) {
        first = false; 
        return sum; 
      }
      if (bust) {
        return "you are done!";
      }
      if(sum + array[0] <= 21) {
        sum += array.shift();
        return sum; 
      } else {
        array.shift();
        bust = true;
        return "bust";
      }
    }
    return player;
  }
  return dealer;
};

/*** Uncomment these to check your work! ***/

/*** DEALER ***/
const deal = blackjack([2, 6, 1, 7, 11, 4, 6, 3, 9, 8, 9, 3, 10, 4, 5, 3, 7, 4, 9, 6, 10, 11]);

/*** PLAYER 1 ***/
const i_like_to_live_dangerously = deal(4, 5);
console.log(i_like_to_live_dangerously()); // should log: 9
console.log(i_like_to_live_dangerously()); // should log: 11
console.log(i_like_to_live_dangerously()); // should log: 17
console.log(i_like_to_live_dangerously()); // should log: 18
console.log(i_like_to_live_dangerously()); // should log: 'bust'
console.log(i_like_to_live_dangerously()); // should log: 'you are done!'
console.log(i_like_to_live_dangerously()); // should log: 'you are done!'

/*** BELOW LINES ARE FOR THE BONUS ***/

/*** PLAYER 2 ***/
const i_TOO_like_to_live_dangerously = deal(2, 2);
console.log(i_TOO_like_to_live_dangerously()); // should log: 4
console.log(i_TOO_like_to_live_dangerously()); // should log: 15
console.log(i_TOO_like_to_live_dangerously()); // should log: 19
console.log(i_TOO_like_to_live_dangerously()); // should log: 'bust'
console.log(i_TOO_like_to_live_dangerously()); // should log: 'you are done!
console.log(i_TOO_like_to_live_dangerously()); // should log: 'you are done!

/*** PLAYER 3 ***/
const i_ALSO_like_to_live_dangerously = deal(3, 7);
console.log(i_ALSO_like_to_live_dangerously()); // should log: 10
console.log(i_ALSO_like_to_live_dangerously()); // should log: 13
console.log(i_ALSO_like_to_live_dangerously()); // should log: 'bust'
console.log(i_ALSO_like_to_live_dangerously()); // should log: 'you are done!
console.log(i_ALSO_like_to_live_dangerously()); // should log: 'you are done!

額外挑戰

挑戰1

問題:

構建functionValidator函數,接受參數爲一個函數型數組和兩個不一樣的數值(稱之爲input和output)。此函數應返回一個特定數組,此特定數組僅包含輸入函數數組中調用input時會返回output的函數。使用reduce!

題解:

// Challenge 1
const functionValidator = (funcArr, input, output) => {
  return funcArr.reduce((acc, curr) => {
    if(curr(input) === output) {
      acc.push(curr);
    }
    return acc;
  }, [])
}

const addFive = num => num + 5;
const multiplyByTwo = num => num * 2;
const subtractOne = num => num - 1;
const fnArr = [addFive, multiplyByTwo, subtractOne];

console.log(functionValidator(fnArr, 5, 10)) // should log [num => num + 5, num => num * 2]

挑戰2

問題:

構建allClear函數,接受參數爲一個由驗證型函數(返回布爾值)組成的數組和一個數值。allClear中應使用reduce來返回一個布爾值從而代表輸入數值是否能夠經過輸入函數數組中的全部函數(即皆返回true)。

題解:

// Challenge 2
const allClear = (funcArr, value) => {
    // // Solution 1: 
    // let indicator = false;
    // indicator = funcArr.reduce((acc, curr) => {
    // if(acc == true && curr(value) === true) {
    // acc = true;
    // } else {
    // acc = false;
    // }
    // return acc;
    // }, true)
    // return indicator; 
  
  // Solution 2: 
  return funcArr.reduce((acc, curr) => {
    if(acc) return curr(value);
    return acc;
  }, true)
}

const isOdd = num => num % 2 === 1;
const isPositive = num => num > 0;
const multipleOfFive = num => num % 5 === 0;
const numFnArr = [isOdd, isPositive, multipleOfFive];
console.log(allClear(numFnArr, 25)) // should log true 
console.log(allClear(numFnArr, -25)) // should log false

挑戰3

問題:

構建numSelectString函數,接受參數爲數值型數組,返回一個字符串。此函數應使用filter、sort和reduce來返回一個僅包含輸入數組中的奇數的字符串,以半角逗號隔開,且升序。

題解:

// Challenge 3
const numSelectString = (numArr) => {
    // // Solution 1: 
    // let strNumArr = "";
    // let numOddArr = [];
    // numOddArr = numArr.reduce((acc, curr) => {
    // if(curr % 2 == 1){
    // acc.push(curr);
    // }
    // return acc;
    // }, [])
    // numOddArr.sort((a,b) => a-b);
    // numOddArr.forEach((el) => {
    // if(strNumArr == "") {
    // strNumArr += el.toString();
    // } else {
    // strNumArr += ", " + el.toString();
    // }
    // })
    // return strNumArr;
  
  // Solution 2: 
  return numArr.sort((a,b) => a - b)
          .filter(num => num % 2 === 1)
          .reduce((acc, curr) => {
            return acc + ", " + curr;
  })
}

const numbers = [17, 34, 3, 12]
console.log(numSelectString(numbers)) // should log "3, 17"

挑戰4

問題:

構建movieSelector函數,接受參數爲一個對象型數組(對象爲電影信息,含id、標題和分數)。請在movieSeletor函數內鏈式調用map、filter和reduce,返回一個僅包含分數大於5的電影標題的數組。電影標題應全爲大寫。

題解:

// Challenge 4
const movieSelector = (moviesArr) => {
    return moviesArr.map( el => { return {"title": el.title.toUpperCase(), "score": el.score}})
          .filter( el => el.score > 5)
            .reduce((acc, curr) => {
        acc.push(curr.title);
            return acc;
      }, [])
}

const movies = [ { id: 1, title: "Pan's Labyrinth", score: 9 }, { id: 37, title: "Manos: The Hands of Fate", score: 2 }, { title: "Air Bud", score: 5 }, { title: "Hackers", score: 7 } ]
console.log(movieSelector(movies)) // should log [ "PAN'S LABYRINTH", "HACKERS" ]

挑戰5

問題:

構建curriedAddThreeNums函數,共接受3個數值做爲參數,每次調用輸入一個數值,共調用三次,以下:

curriedAddThreeNums(1)(3)(7) //should return 10

題解:

// Challenge 5
const curriedAddThreeNums = (num1) => {
    return (num2) => {
    return (num3) =>{
      return num1 + num2 + num3;
    }
  }
}

console.log(curriedAddThreeNums(3)(-1)(1)); // should log 3

挑戰6

問題:

部分藉助你在挑戰5中建立的curriedAddThreeNums函數來構建curriedAddTwoNumsToFive函數,此函數接受兩個數組參數,每次調用輸入一個數值,共兩次,最終求得兩個數值與5的和,以下:

curriedAddTwoNumsToFive(6)(7) //should return 18

題解:

// Challenge 6
const curriedAddTwoNumsToFive = curriedAddThreeNums(5);

console.log(curriedAddTwoNumsToFive(6)(7)) // should log 18

13.raven

相關文章
相關標籤/搜索