freecodecamp中级算法题详解

1,388 阅读16分钟

记录下最近刷的freecodecamp的中级算法题,难度适中,一套做下来大大的提高的对数组字符串对象等的操作能力,对面试帮助很大哦~刷面试题的朋友们可以看看~

一、范围内的数字求和

给出一个含有两个数字的数组,我们需要写一个函数,让它返回这两个数字间所有数字(包含这两个数字)的总和。
注意,较小数不一定总是出现在数组的第一个元素。

解法一:

function sumAll(arr){
     let sum = 0;
     // 求传入的数组的最小值
     let minNum = Math.min(arr[0],arr[1])
     // 求传入的数组的最大值
     let maxNum = Math.max(arr[0],arr[1])
     for(let i = minNum; i <= maxNum; i++){
         sum += i
     }
     return sum
}

解法二:

function sumAll(arr){
    // 对传入的数组进行从小到大的排序
    arr.sort((a,b) => {
        return a - b
    })
    let sum = 0
    for(let i = arr[0]; i <= arr[1]; i++){
        sum += i
    }
    return sum
}

解法三:

function sumAll(arr){
    // 对传入的数组进行从小到大的排序
    arr.sort((a,b) => {
        return a - b
    })
    let startNum = arr[0]
    let endNum = arr[1]
    // 等差数列求和公式 (首项+末项)×项数/2
    // 举例:1+2+3+4+5+6+7+8+9=(1+9)×9/2=45
    let sum = (endNum - startNum + 1) * (startNum + endNum) / 2
    return sum
}

解法四:

 function sumAll(arr){
    let num1 = arr[0]
    let num2 = arr[1]
    // 等差数列求和公式 (首项+末项)×项数/2
    // 举例:1+2+3+4+5+6+7+8+9=(1+9)×9/2=45
    let sum = (Math.abs(num2 - num1) + 1) * (num1 + num2) / 2
    return sum
}

解法四没有对传入的数组进行排序,进行项数的计算时相减可能得到负数,所以采用Math.abs(num2 - num1)获取两数相减的绝对值。

二、区分两个数组

在这道题目中,我们需要写一个函数,比较两个数组,返回一个新的数组。这个新数组需要包含传入的两个数组所有元素中,仅在其中一个数组里出现的元素。如果某个元素同时出现在两个数组中,则不应包含在返回的数组里。换言之,我们需要返回这两个数组的对称差。

解法一:

function diffArray(arr1, arr2) {
    var newArr = [];
    // 连接两个数组
    let arr = arr1.concat(arr2)
    for(let i = 0;i < arr.length; i++ ){
        /* 若数组从前往后查找该元素得到的索引和从后往前
        查找该元素得到的索引相同,则该数组中该元素无重复值 */
        if(arr.indexOf(arr[i]) === arr.lastIndexOf(arr[i])){
            newArr.push(arr[i])
        }
    }
    return newArr;
}

解法二:

 function diffArray(arr1, arr2) {
    var newArr = [];
    // 找出arr1中arr2没有的元素
    for(let i = 0; i < arr1.length; i++){
        if(arr2.indexOf(arr1[i]) === -1){
            newArr.push(arr1[i])
        }
    }
    // 找出arr2中arr1没有的元素
    for(let i = 0; i < arr2.length; i++){
        if(arr1.indexOf(arr2[i]) === -1){
            newArr.push(arr2[i])
        }
    }
    return newArr;
}

解法三:

 function diffArray(arr1, arr2) {
    var newArr = [];
    // 循环两数组,去掉同时出现在两数组中的元素
    for(let i = 0; i < arr1.length; i++){
       for(let j = 0; j < arr2.length; j++){
           if(arr1[i] === arr2[j]){
               arr1.splice(i,1)
               arr2.splice(j,1)
               i--
               j--
           }
       }
    }
    newArr = arr1.concat(arr2)
    return newArr;
}

解法四:

function diffArray(arr1, arr2) {
    // 先连接两数组,然后过滤出仅在其中一个数组中出现过的元素
    return arr1.concat(arr2).filter((item) => !arr1.includes(item) || !arr2.includes(item));
}

三、瞄准和消灭

在这道题目中,我们要写一个叫destroyer的函数。传给它的第一个参数是数组,我们称他为初始数组。后续的参数数量是不确定的,可能有一个或多个。你需要做的是,从初始数组中移除所有与后续参数相等的元素,并返回移除元素后的数组。

解法一:

function destroyer(arr,...arg) {
    for(var i = 0; i < arg.length;i++){
        for(var j = 0;j < arr.length;j++){
            if(arg[i] === arr[j]){
                arr.splice(j,1)
                j--
            }
        }
    }
    return arr;
}

解法二:

function destroyer(arr,...arg) {
    return arr.filter(item => !arg.includes(item))
}

四、罗密欧与朱丽叶

在这道题目中,我们要写一个函数,它接收两个参数:第一个参数是对象数组,第二个参数是一个对象。我们需要从对象数组中找出与第二个参数相等或包含第二个参数的所有对象,并以对象数组的形式返回。其中,相等的意思是原数组中的对象与第二个参数中对象的所有键值对完全相等;包含的意思是只要第二个参数中对象的所有键存在于原数组对象中,且它们对应的值相同即可

解法一:

function whatIsInAName(collection, source) {
    var arr = [];
    for(var i = 0; i < collection.length;i++){
        // 判断是否完全相等
        if(JSON.stringify(collection[i]) === JSON.stringify(source)){
            arr.push(collection[i])
        }else{
            let flag = false
            Object.keys(source).map(v => {
                // 判断是否包含第二个参数的所有对象
                if(!collection[i][v] || collection[i][v] !== source[v]){
                    flag = true
                }
            })
            if(!flag){
                arr.push(collection[i])
            }
        }
    }
    return arr;
}

解法二:

function whatIsInAName(collection, source) {
    let sourceKeys = Object.keys(source)
    return collection.filter((item) => {
        for(let i = 0; i < sourceKeys.length; i++){
            //过滤数组中不包含第二个参数键值对的元素或包含所有的键但是值不相等的元素
            if(!item.hasOwnProperty(sourceKeys[i]) || item[sourceKeys[i]] !== source[sourceKeys[i]]){
                return false
            } 
        }
        return true
    })
}

解法三:

function whatIsInAName(collection, source) {
    let sourceKeys = Object.keys(source)
    return collection.filter((item) => {
        return sourceKeys.every(key =>item.hasOwnProperty(key) && item[key] === source[key])
    })
}

五、短线连接格式

在这道题目中,我们需要写一个函数,把一个字符串转换为“短线连接格式”。短线连接格式的意思是,所有字母都是小写,且用-连接。比如,对于HelloWorld,应该转换为hello-world;对于I love_Javascript-VeryMuch,应该转换为i-love-javascript-very-much。

解法一:

function spinalCase(str) {
    // 正则匹配空格和下划线
    var regex = /\s+|_+/g;
    // 将所有的驼峰形式的字母进行拆分,中间加空格
    str = str.replace(/([a-z])([A-Z])/g, '$1 $2');
    return str.replace(regex, '-').toLowerCase();
}

解法二:

function spinalCase(str) {
    str = str.replace(/([a-z])([A-Z])/g, '$1 $2');
    return str.toLowerCase().split(/(?:_| )+/).join("-");
}

正则中()表示捕获分组,()会把每个分组里的匹配的值保存起来,使用$n(n是一个数字,表示第n个捕获组的内容)表示
正则中(?:)表示非捕获分组,和捕获分组唯一的区别在于,非捕获分组匹配的值不会保存起来

解法三:

function spinalCase(str) {
    return str.split(/\s|_|(?=[A-Z])/).join('-').toLowerCase()
}

(?=pattern) 正向先行断言
代表字符串中的一个位置,紧接该位置之后的字符序列能够匹配pattern。
(?!pattern) 负向先行断言
代表字符串中的一个位置,紧接该位置之后的字符序列不能匹配pattern。

六、儿童黑话

在这道题目中,我们需要写一个函数,把传入的字符串翻译成“儿童黑话”。
儿童黑话的基本转换规则很简单,只需要把一个英文单词的第一个辅音字母或第一组辅音从移到单词的结尾,并在后面加上ay即可。
在英语中,字母 a、e、i、o、u为元音,其余的字母均为辅音。辅音从的意思是连续的多个辅音字母。
额外地,如果单词本身是以元音开头的,那只需要在结尾加上way。
在本题中,传入的单词一定会是英文单词,且所有字母均为小写

解法一:

function translatePigLatin(str) {
    let pigLatin = ''
    // 正则匹配元音字母
    let regex = /[aeiou]/gi
    if(str[0].match(regex)){   // 判读首字母是否是元音字母
        pigLatin = str + 'way'
    }else if(str.match(regex) === null){ //整个字符串都由辅音字母组成
        pigLatin = str + 'ay'
    }else{  // 由辅音字母开头
        var vowelIndice = str.indexOf(str.match(regex)[0])
        pigLatin = str.substr(vowelIndice) + str.substr(0,vowelIndice) + 'ay'
    }
    return pigLatin;
}

解法二:

function translatePigLatin(str) {
    // 查找字符串中第一个元音字母所在位置
    function check(obj){
        return ['a','e','i','o','u'].indexOf(str.charAt(obj)) === -1 && obj < str.length ? check(obj + 1) : obj
    }
    return str.substr(check(0)).concat(check(0) === 0 ? 'w' : str.substr(0,check(0)) + 'ay');
}

解法三:

function translatePigLatin(str) {
    let strArr = []
    let tmpChar = ''
    // 判断是否是辅音字母
    function isConsonant(char){
        return !/[aeiou]/.test(char)
    }
    if(!isConsonant(str.charAt(0))){
        return str + 'way'
    }else{
        strArr = str.split("")
    }
    //如果是辅音字母则移至数组末尾,直到遇到元音字母则停止循环
    while(isConsonant(strArr[0])){
        tmpChar = strArr.shift()
        strArr.push(tmpChar)
    }
    return strArr.join("") + 'ay'
}

七、搜索和替换

在这道题目中,我们需要写一个字符串的搜索与替换函数,它的返回值为完成替换后的新字符串。这个函数接收的第一个参数为待替换的句子。第二个参数为句中需要被替换的单词。第三个参数为替换后的单词。

解法一:

function myReplace(str, before, after) {
    // 判断代替换的单词的首字母是否是大写
    if(before.charAt(0).match(/[A-Z]/)){
        after = after.charAt(0).toUpperCase() + after.slice(1)
    }   
    return str.replace(before,after);
}

解法二:

function myReplace(str, before, after) {
    let index = str.indexOf(before)
    // 判断代替换的单词的首字母是否是大写
    if(str[index] === str[index].toUpperCase()){
        after = after.charAt(0).toUpperCase() + after.slice(1)
    }
    return str.replace(before,after);
}

八、DNA 配对

在这道题目中,我们需要写一个函数,为 DNA中的碱基配对。这个函数只接收一个表示碱基的字符串为参数,最后返回完成配对的二维数组。

碱基对 由一对碱基组成。碱基有四种,分别为 A(腺嘌呤)、T(胸腺嘧啶)、G(鸟嘌呤)和 C(胞嘧啶)。配对原则是:A 与 T 配对,C 与 G 配对。我们需要根据这个原则对传入的所有碱基进行配对。

对于每个传入的碱基,我们应采用数组的形式展示配对结果。其中,传入的碱基需要作为数组的第一个元素出现。最终返回的数组中应当包含参数中每一个碱基的配对结果。

比如,传入的参数是 GCG,那么函数的返回值应为 [["G", "C"], ["C","G"],["G", "C"]]

解法一:

 function pairElement(str) {
    let strArr = str.split("")
    let resArr = []
    strArr.map(v => {
        switch(v){
            case 'A':
                resArr.push(['A','T'])
                break
            case 'T':
                resArr.push(['T','A'])
                break
            case 'G':
                resArr.push(['G','C'])
                break
            case 'C':
                resArr.push(['C','G'])
                break
        }
    })
    return resArr;
}

解法二:

function pairElement(str) {
    let pairs = {
        "A":"T",
        "T":"A",
        "G":"C",
        "C":"G"
    }
    let arr = str.split("")
    return arr.map(v=>[v,pairs[v]])
}

九、丢失的字母

在这道题目中,我们需要写一个函数,找到传入的字符串里缺失的字母并返回它。 判断缺失的依据是字母顺序,比如 abcdfg 中缺失了 e。而 abcdef 中就没有字母缺失,此时我们需要返回undefined。

解法一:

function fearNotLetter(str) {
    for(let i = 1; i < str.length;i++){
        // 判断字符串该字符的编码减一是否等于其前一个字符的编码
        if(str.charCodeAt(i-1) !== str.charCodeAt(i) - 1 ){
            return String.fromCharCode(str.charCodeAt(i-1) + 1)
        }
    }
    return undefined;
}

解法二:

function fearNotLetter(str) {
    for(let i = 0; i < str.length;i++){
        let code = str.charCodeAt(i)
        // 判断当前字符的编码是否等于字符串第一个字符的编码加上索引值
        if(code !== str.charCodeAt(0) + i){
            return String.fromCharCode(str.charCodeAt(0) + i)
        }
    }
    return undefined
}

解法三:

function fearNotLetter(str) {
    let compare = str.charCodeAt(0)
    let missing 
    str.split("").map((letter,index) => {
        if(str.charCodeAt(index) === compare){
            ++compare
        }else{
            missing = String.fromCharCode(compare)
        }
    })
    return missing
}

十、集合排序

在这道题目中,我们需要写一个函数,它接收两个或多个数组为参数。我们需要对这些数组中所有元素进行去除重复元素的处理,并以数组的形式返回去重结果。需要注意的是,结果数组中的元素顺序必须与其传入的顺序保持一致。

解法一:

function uniteUnique(...arg) {
    let concatArr = []
    arg.map(item => concatArr.push(...item))
    return Array.from(new Set(concatArr));
}

解法二:

function uniteUnique(...arg) {
    let concatArr = []
    let uniqueArr = []
    arg.map(item => concatArr.push(...item))
    concatArr.map(item => {
        if(uniqueArr.indexOf(item) === -1){
            uniqueArr.push(item)
        }
    })
    return uniqueArr
}

解法三:

function uniteUnique(...arg){
    let concatArr = []
    arg.map(item =>{
        item.map(item1 => {
            if(concatArr.indexOf(item1) === -1){
                concatArr.push(item1)
            }
        })
    })
    return concatArr
}

解法四:

function uniteUnique(...arg){
    let flatArr = [].concat(...arg)
    return [...new Set(flatArr)]
}

解法五:

function uniteUnique(...arg) {
    let concatArr = []
    let uniqueArr = []
    arg.map(item => concatArr.push(...item))
    uniqueArr = concatArr.filter((item,index) => {
       return concatArr.indexOf(item) === index
    })
    return uniqueArr
}

十一、转换HTML实体

在这道题目中,我们需要写一个转换 HTML entity 的函数。需要转换的 HTML entity 有&、<、>、"(双引号)和'(单引号)。转换的规则你可以在 W3C 官网找到。

解法一:

function convertHTML(str) {
    var temp = str.split('');
    for (var i = 0; i < temp.length; i++) {
        switch (temp[i]) {
            case '<':
                temp[i] = '&lt;';
                break;
            case '&':
                temp[i] = '&amp;';
                break;
            case '>':
                temp[i] = '&gt;';
                break;
            case '"':
                temp[i] = '&quot;';
                break;
            case "'":
                temp[i] = "&apos;";
                break;
        }
    }
    temp = temp.join('');
    return temp;
}

解法二:

function convertHTML(str) {
    str = str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,"&apos;");
    return str;
}

解法三:

function convertHTML(str) {
    htmlEntities={
        '&':'&amp;',
        '<':'&lt;',
        '>':'&gt;',
        '"':'&quot;',
        '\'':"&apos;"
    };
    return str.split('').map(entity => htmlEntities[entity] || entity).join('');
}

十二、求斐波那契数组中的奇数之和

在这道题目中,我们需要写一个函数,参数为一个正整数num。它的作用是计算斐波那契数列中,小于或等于num的奇数之和。

斐波那契数列中,第一和第二个数字都是 1,后面的每个数字由之前两数相加得出。斐波那契数列的前六个数字分别为:1、1、2、3、5、8。

解法一:

function sumFibs(num) {
    let fibsArr = [1,1]
    let sumFibs = 0
    if(num < 2){
        sumFibs = 1
    }else if(num >= 2){
        let i = 0
        while(fibsArr[i] + fibsArr[i+1] <= num){
            fibsArr.push(fibsArr[i] + fibsArr[i+1])
            i ++ 
        }
        //也可采用map循环的方式
        // fibsArr.map(v => {
        //     if(v % 2 !== 0){
        //         sumFibs += v
        //     }
        // })
        sumFibs = fibsArr.reduce((acc,curr) =>{
            return acc + curr * (curr % 2)
        })
    }
    return sumFibs;
}

解法二:

function sumFibs(num) {
    let prevNumber = 0;
    let currNumber = 1;
    let result = 0;
    while(currNumber <= num){
        if(currNumber % 2 !== 0){
            result += currNumber
        }

        currNumber += prevNumber
        prevNumber = currNumber - prevNumber
    }
   return result
}

十三、对所有素数求和

在这道题目中,我们需要写一个函数,它接收一个数字参数num,返回值为不大于这个数字的所有质数之和。

质数是大于 1 且仅可以被 1 和自己整除的数。比如,2 就是一个质数,因为它只可以被 1 和 2(它本身)整除。

注意,传入函数的num不一定是质数。

解法一:

function sumPrimes(num) {
    let sum = 0
    for(let i = 2; i <= num; i++){
        let isPrime = true
        for(let j = 2; j < i; j++){
            //能被不是1且不是它自己的数整除则说明不是质数
            if(i % j === 0){ 
                isPrime = false
            }
        }
        if(isPrime){
            sum += i
        }
    }
    return sum;
}

解法二:

function sumPrimes(num) {
    // 创建一个从0到num的数组
    let arr = Array.from({length: num+1}, (v, k) => k).slice(2); 
    let onlyPrimes = arr.filter( (n) => { 
        let m = n-1;
        while (m > 1 && m >= Math.sqrt(n)) { 
            if ((n % m) === 0) 
                return false;
                m--;
            }
            return true;
        });
    return onlyPrimes.reduce((a,b) => a+b); 
}

解法三:

function sumPrimes(num) {
    // 判断是否是质数
    function isPrime(number){
        for (i = 2; i <= number; i++){
            if(number % i === 0 && number!= i){
                return false;
            }
        }
        return true;
    }
    if (num === 1){
        return 0;
    }
    if(isPrime(num) === false){
        return sumPrimes(num - 1);
    }

    if(isPrime(num) === true){
        return num + sumPrimes(num - 1);
    }
}

十四、最小公倍数

在这道题目中,我们需要写一个函数,它接收一个包含两个数字的数组参数arr,它的返回值为这两个数字范围内所有数字(包含这两个数字)的最小公倍数。

注意,较小数不一定总是出现在数组的第一个元素。

解法一:

function smallestCommons(arr) {
    // 先对数组进行排序
    arr.sort((a,b) => {
        return a - b
    })
    let newArr = []
    for(let i = arr[0]; i <= arr[1]; i++){
        newArr.push(i)
    }
    let quot = 0
    let loop = 1
    let n
    // 两两依次求出最小公倍数 
    do{
        quot = newArr[0] * loop * newArr[1]
        for(n = 2; n < newArr.length; n++){
            if(quot % newArr[n] !== 0){
                break
            }
        }
        loop++
    }while(n !== newArr.length)
    return quot;
}

解法二:

function smallestCommons(arr){
    let minNum = Math.min(arr[0],arr[1])
    let maxNum = Math.max(arr[0],arr[1])
    let newArr = []
    for(let i = minNum; i <= maxNum; i++){
        newArr.push(i)
    }
    // 辗转相除法求出两数之间的最大公约数
    function gcdFn(x,y){
        if(y === 0){
            return x
        }else{
            return gcdFn(y,x%y)
        }
    }

    // 最小公倍数等于两数之积除以最大公约数
    let lcm = newArr[0]
    for(let j = 1; j < newArr.length; j++){
        let gcd = gcdFn(lcm,newArr[j])
        lcm = (lcm * newArr[j]) / gcd
    }

    return lcm
}

解法三:

function smallestCommons(arr) {
    let min = Math.min.apply(null, arr);
    let max = Math.max.apply(null, arr);

    let smallestCommon = lcm(min, min + 1);

    while(min < max) {
        min++;
        smallestCommon = lcm(smallestCommon, min);
    }

    return smallestCommon;
}

// 求两数最大公约数
function gcd(a, b) {
    while (b > 0) {
        let tmp = a;
        a = b;
        b = tmp % b;
    }
    return a;
}
// 求两数最小公倍数
function lcm(a, b) {
    return (a * b / gcd(a, b));
}

十五、放弃

在这道题目中,我们需要写一个函数,它接收两个参数,分别为一个数组arr以及一个函数func。我们需要从数组的第一个元素开始,用func来检查数组的每项。函数最终的返回值也是一个数组,它由原数组中第一个使得func为true的元素及其之后的所有元素组成。 如果数组中的所有元素都不能让func为true,则返回空数组[]。

解法一:

function dropElements(arr, func) {
   let len = arr.length
    for(var i = 0; i < len;i++){
        // 若该元素不能让func为true,则删除该元素
        if(!func(arr[i])){
            arr.splice(i,1)
            i--
        }else{
            break
        }
    }
    return arr;
}

解法二:

function dropElements(arr,func){
    let len = arr.length
    for(let i = 0; i < len; i++){
        if(!func(arr[0])){
            arr.shift()
        }else{
            break
        }
    }
    return arr
}

解法三:

function dropElements(arr,func){
    return arr.slice(arr.findIndex(func) > -1 ? arr.findIndex(func):arr.length)
}

findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。

解法四:

function dropElements(arr, func) {
    while(arr.length > 0 && !func(arr[0])) {
        arr.shift();
    }
    return arr;
}

十六、扁平化

在这道题目中,我们需要写一个数组扁平化的函数。 注意,你写的函数应该能够处理数组多级嵌套的情况。比如,[1, [2], [3,[4]]]在扁平化处理后的结果应为[1, 2, 3, 4]。

解法一:

function steamrollArray(arr) {
    let flattenedArray  = []

    let flatten = function(arg){
        // 如果该元素是数组则进行递归
        if(Array.isArray(arg)){
            for(let i in arg){
                flatten(arg[i])
            }
        }else{
            flattenedArray.push(arg)
        }
    }

    arr.forEach(flatten);
}

解法二:

function steamrollArray(arr){
    let flat = [].concat(...arr)
    return flat.some(Array.isArray) ? steamrollArray(flat) : flat
}

解法三:

function steamrollArray(arr){
    return arr.toString()
        .replace(",,",",")
        .split(",")
        .map(v =>{
            if(v == '[object Object]'){
                return {}
            }else if(isNaN(v)){
                return v
            }else {
                return parseInt(v)
            }
        })
}

十七、二进制转化

在这道题目中,我们需要写一个把二进制输入转换成英文句子的函数。 传入函数的二进制字符串会用空格作为分隔符。

解法一:

function binaryAgent(str) {
    // 将字符串以空格为分隔符进行划分
    let arr = str.split(" ")
    // 求出每一位二进制的十进制数
    arr = arr.map(v => {
        return translate(v.split(""))
    })
    // 二进制转十进制,十进制转为相应的字符
    function translate(item){
        let sum = 0
        item.map((v,i) => {     
            sum += parseInt(v) * Math.pow(2,item.length - i - 1)
        })
        return String.fromCharCode(sum)
    }
    return arr.join("");
}

解法二:

function binaryAgent(str){
    let biString = str.split(" ")
    let uniString = []

    for(let i = 0; i < biString.length; i++){
        uniString.push(String.fromCharCode(parseInt(biString[i],2)))
    }
    return uniString.join("")
}

parseInt(string, radix)
string 必需。要被解析的字符串
可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。

解法三:

function binaryAgent(str){
    return String.fromCharCode(...str.split(" ").map(char => parseInt(char,2)))
}

十八、真假值判断

在这道题目中,我们需要写一个函数,它接收两个参数。第一个参数为对象数组collection,第二个参数为一个字符串pre,代表对象的一个键(key)。我们需要检查对象数组中每个对象的pre属性对应的值是否都为 “真”(truthy)。如果是,则返回true,否则返回false。 JavaScript 中,如果一个值在 Boolean 的上下文中(比如if语句)可以被执行为true,那么这个值就被认为是truthy的。

解法一:

function truthCheck(collection, pre) {
    return collection.every(item => item[pre])
}

解法二:

function truthCheck(collection,pre){
    return collection.every(item => {
        return item.hasOwnProperty(pre) && Boolean(item[pre])
    })
}

解法三:

function truthCheck(collection, pre) {
    var counter = 0;
    for (var c in collection) {
        if (collection[c].hasOwnProperty(pre) && Boolean(collection[c][pre])) {
            counter++;
        }
    }
    return counter == collection.length;
}

十九、可选参数

在这道题目中,我们需要写一个求和的函数,但它接收的参数数量不定。如果传入了两个参数,那么直接返回两数之和即可。如果只传入一个参数,那我们应该返回另一个函数用来接收下一个参数,然后求出两数之和。

比如,addTogether(2, 3)应该返回5。而addTogether(2)应该返回一个函数。

然后我们调用这个返回的函数,并给它传入另一个用于求和的值:

var sumTwoAnd = addTogether(2);

sumTwoAnd(3)此时应返回5。

只要其中任何一个参数不是数字,那我们就应返回undefined。

解法一:

function addTogether() {
    // 判断是否是数字
    let checkNum = function(num){
        if(typeof num !== 'number'){
            return undefined
        }else{
            return num
        }
    }
    if(arguments.length > 1){
        let a = checkNum(arguments[0])
        let b = checkNum(arguments[1])
        if(a === undefined || b === undefined){
            return undefined
        }else{
            return a + b
        }
    }else{
        let c = arguments[0]
        if(checkNum(c)){
            return function(arg2){
                if(c === undefined || checkNum(arg2) === undefined){
                    return undefined
                }else {
                    return c + arg2              
                }
            }
        }
    }
}

解法二:

function addTogether() {
    var args = Array.from(arguments);
    return args.some(n => typeof n !== 'number') ? 
           undefined: 
           args.length > 1 ?
                args.reduce((acc, n) => acc += n):
                (n) => typeof n === "number" ? 
                    n + args[0]:
                    undefined;
}

参考地址:
1、learn.freecodecamp.one/

有更多解题思路的小伙伴欢迎留言哦~