@冒泡的马树
题库原地址:http://csbin.io/functional
高阶函数
挑战1
问题:
构建一个addTwo函数,作用为承受一个参数并将参数加2。
题解:
// Challenge 1const 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"拼接。
题解:
// Challenge 2const addS = (word) => { return word.toString() + 's';};// Uncomment these to check your workconsole.log(addS('pizza'));console.log(addS('bagel'));
挑战3
问题:
构建一个map函数,其承受两个参数:
- 数值型数组
- 回调函数——一个利用于上述数值型数组中的每一个元素的函数(于map函数内)
map函数的返回值为蕴含上述数值型数组元素一一运行回调函数后生成的元素值的新数组。
map([1,2,3,4,5], multiplyByTwo); //-> [2,4,6,8,10]multiplyByTwo(1); //-> 2multiplyByTwo(2); //-> 4
题解:
// Challenge 3const 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 4const 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 5const 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 6const 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 7const 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 8const 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 9const 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 10const 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 11const 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: trueconsole.log(commutative(multBy3, subtract5, 10)); // should log: falseconsole.log(commutative(divBy4, subtract5, 48)); // should log: false
挑战12
问题:
构建objectFilter函数,第一个参数为对象,第二个参数为回调函数。objectFilter函数会返回特定对象。此特定对象所蕴含的属性为输出对象中值与其对应键传入回调函数失去的返回值统一的键值对。
题解:
// Challenge 12const 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 13const 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: 100console.log(rating(checks, 66)); // should log: 75
挑战14
问题:
构建pipe函数,承受参数为一个由函数组成的数组和一个值。pipe会将输出值输出到数组的第一个函数中,而后再将失去的输入值输出到第二个函数中,而后输入值又再输出到第三个函数中,始终上来,直到失去数组的最初一个函数的输入值。pipe会返回这个最终输入值。
题解:
// Challenge 14const 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 15const 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 createdfunction1(); //should console.log('hello');
题解:
// Challenge 1const 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 createdprintSample(); //should console.log('sample');printHello(); //should console.log('hello');
题解:
// Challenge 2const 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 3const 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 3addByTwo(2); //should return 4addByTwo(3); //should return 5const addByThree = addByX(3);addByThree(1); //should return 4addByThree(2); //should return 5const addByFour = addByX(4);addByFour(4); //should return 8addByFour(10); //should return 14
题解:
// Challenge 4const addByX = (x) => { const outerInput = x; const innerFunction = (innerInput) => { return x + innerInput; } return innerFunction;};const addByTwo = addByX(2);// now call addByTwo with an input of 1console.log(addByTwo(1));// now call addByTwo with an input of 2console.log(addByTwo(2));
挑战5
问题:
构建once函数,承受参数为一个回调函数并返回一个特定函数。当特定函数被第一次调用时,其会调用回调函数并返回输入值。如果其不是被第一次调用,则特定函数仅仅返回第一次调用时失去的回调函数返回值,而不是再次运行回调函数。
题解:
// Challenge 5const 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 6console.log(onceFunc(10)); //should log 6console.log(onceFunc(9001)); //should log 6
挑战6
问题:
构建after函数,承受一个数字n和一个回调函数作为参数。回调函数须要在通过after构建的函数运行第n次时才被运行。
题解:
// Challenge 6const 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 printedafterCalled(); // -> nothing is printedafterCalled(); // -> 'hello' is printed
挑战7
问题:
构建delay函数,作用为承受一个回调函数作为第一个参数,一个数值n(单位为毫秒)作为第二个参数,返回一个特定函数。delay构建的特定函数被调用后,须经n毫秒后才运行回调函数。任何其余赋给特定函数的参数会在n毫秒后被回调函数应用。提醒:钻研setTimeout();
题解:
// Challenge 7const 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 8const 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 8const 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 9const 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: 0console.log(avgSoFar(4)); // should log: 4console.log(avgSoFar(8)); // should log: 6console.log(avgSoFar()); // should log: 6console.log(avgSoFar(12)); // should log: 8console.log(avgSoFar()); // should log: 8
挑战10
问题:
构建makeFuncTester函数,承受参数为一个二维数组(其中第二维数组仅含两个元素),返回一个接管回调函数作为参数的特定函数。当二维数组的每一个子数组的第一个元素输出到回调函数时都产生与第二个元素雷同的返回值时,特定函数返回ture,否则特定函数返回false。
题解:
// Challenge 10const 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: falseconsole.log(shouldCapitalizeLast(capLastAttempt2)); // should log: true
挑战11
问题:
构建makeHistory函数,承受一个数值参数n(充当限定值)并返回一个特定函数(承受字符串作为参数)。特定函数会存储限定个数为n的最近输出到此特定函数中的字符串参数历史(每次调用存储一次)。每次一个字符串被输出到特定函数中,特定函数会返回拼接“done”于此字符串后的新字符串(空格作为距离)。然而,如果输出字符串为“undo”,特定函数会删除字符串参数历史中的最近字符串值,返回拼接“undone”于此最近字符串后的新字符串(空格作为距离)。如果输出字符串“undo”时特定函数中的字符串参数历史已为空,那么特定函数会返回字符串“nothing to undo”。
题解:
// Challenge 11const 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函数时,它会返回下列两种状况中的一种:
- 输出blackjack函数的数值型数组的第一个数值加上输出DEALER函数中的两个数值参数之和失去的和,如果和小于等于21,返回此和;
- 如果和大于21,返回字符串“bust”。
如果第二次调用PLAYER函数时已返回"bust",则接下来PLAYER函数的每次调用皆会返回字符串“you are done!"(不过不同于“bust",输入”you are done!“时不会应用数值型数组中的数值)。如果第二次调用PLAYER函数时并未返回”bust“,则接下来调用PLAYER函数时会返回下列两种状况中的一种:
- 最近一次的和值加上数值型数组的下一个数值元素,如果这个求和后果小于等于21的话,返回此和;
- 返回“bust”如果求和后果大于21。
再次申明,如果其返回"bust",则接下来PLAYER函数的每次调用皆会返回字符串“you are done!",否则,PLAYER函数会持续应用最近一次和值与数值型数组的下一个数值元素求和,始终上来。
你能够假如给定的数值型数组有足够多的数值元素从而会在用完数组元素之前失去“bust"。
题解:
// Challenge 12const 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: 9console.log(i_like_to_live_dangerously()); // should log: 11console.log(i_like_to_live_dangerously()); // should log: 17console.log(i_like_to_live_dangerously()); // should log: 18console.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: 4console.log(i_TOO_like_to_live_dangerously()); // should log: 15console.log(i_TOO_like_to_live_dangerously()); // should log: 19console.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: 10console.log(i_ALSO_like_to_live_dangerously()); // should log: 13console.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 1const 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 2const 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 3const 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 4const 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 5const 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 6const curriedAddTwoNumsToFive = curriedAddThreeNums(5);console.log(curriedAddTwoNumsToFive(6)(7)) // should log 18