Javascript算法练习(六)

Javascript算法练习(六)

diffArray:取出两个数组中非共有的元素,组合成新数组返回

练习filter的使用

较简单的方法就是调用filter去过滤出两个数组中彼此不存在的元素

  • filter + concat

    /**
     * 获取两个数组中非共有部分
     * @param  {[type]} arr1 [description]
     * @param  {[type]} arr2 [description]
     * @return {[Array]}      返回两个数组中非共有部分组成的新数组
     */
    function diffArray(arr1, arr2) {
    
        if ( !arr1 || !arr2 ) return;
    
        // 过滤arr1中共有部分
        var arr1Diff = arr1.filter(function(value){
            return  arr2.indexOf(value) == -1;
        });
    
        // 过滤arr2中共有部分
        var arr2Diff = arr2.filter(function(value){
            return  arr1.indexOf(value) == -1;
        });
    
        // 连接两个非共有数组
        return arr1Diff.concat(arr2Diff);
    }

convertToRoman: 将阿拉伯数字转换成罗马数字表示形式,支持范围(1-3999)

  • 思路:取出数字各个位的数字(千位,百位,十位,个位),然后减一之后,当作罗马数字字符串数字下表去取相对应的罗马数字表示形式,最后组合成字符串,即得到阿拉伯数字对应的罗马数字表示形式。

    /**
     * 将1 - 3999数字转成罗马数字表示形式,如:
     * @param  {[type]} num [description]
     * @return {[type]}     [description]
     */
    function convertToRoman( number ) {
        // 数字范围限制
        if ( number >= 4000 || number <= 0 ) {
            console.log( number + " is not between 1 and 3999, please check your number !" );
            return;
        }
    
        var romaStr = "";
    
        var thousand    = parseInt(number / 1000),              // 千位数
            hundred     = parseInt(number % 1000 / 100),        // 百位数
            ten         = parseInt(number % 1000 % 100 / 10),   // 十位数
            single      = parseInt(number % 1000 % 100 % 10);   // 个位数
    
        console.log("thousand = " + thousand + ", hundred = " + hundred + ", ten = " + ten, ", single = " + single);
    
        if ( thousand > 0 ) romaStr += ["M", "MM", "MMM"][thousand - 1];
        if ( hundred > 0 )  romaStr += ["C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"][hundred - 1];
        if ( ten > 0 )      romaStr += ["X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"][ten - 1];
        if ( single > 0 )   romaStr += ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"][single - 1];
    
        return romaStr;
    }
    
    // 测试结果:
    convertToRoman(3425)
    algorithm-06.html:32 thousand = 3, hundred = 4, ten = 2 , single = 5
    "MMMCDXXV"
    convertToRoman(3999)
    algorithm-06.html:32 thousand = 3, hundred = 9, ten = 9 , single = 9
    "MMMCMXCIX"
    convertToRoman(4000)
    algorithm-06.html:21 4000 is not between 1000 and 3999, please check your number !
    undefined
    convertToRoman(3440)
    algorithm-06.html:32 thousand = 3, hundred = 4, ten = 4 , single = 0
    "MMMCDXL"
    convertToRoman(1)
    algorithm-06.html:32 thousand = 0, hundred = 0, ten = 0 , single = 1
    "I"
    convertToRoman(10)
    algorithm-06.html:32 thousand = 0, hundred = 0, ten = 1 , single = 0
    "X"
    convertToRoman(239)
    algorithm-06.html:32 thousand = 0, hundred = 2, ten = 3 , single = 9
    "CCXXXIX"

findAllRightEleFromObjArray 从对象数组中找出包含目标对象中所有键值对的对象元素,组成新数组返回

  • 通过使用数组方法:map()遍历数组,和对象构造器方法:Object.keys()去获取对象中所有键组成的数组

    • map: 通过遍历数组每个元素,并且绑定一个处理函数,最终的返回值是一个数组类型,包含了对每个值的处理结果
    • Object.keys:返回对象中所有的键字符串形式组成新的数组
    function findAllRightEleFromObjArray(collection, source) {
    
        var rightObjArr = [],
            has = true;
    
        // get all keys of source
        var srcKeys     = Object.keys(source);
    
        collection.map(function (obj, index) {
            srcKeys.map(function(keyV){
                if ( obj.hasOwnProperty(keyV) ) { // has
                    // 判断值是否相同,如果不同记录为false
                    if ( obj[keyV] != source[keyV] ) has = false;
                } else {
                    // 到这里,表示该属性不存在
                    has = false;
                }
            }); 
    
            // 只要has为false,表示至少有一个source中的键值对不被包含在collection的对象中
            // 则不符合条件,不添加到最后的符合要求的结果中
            if ( has ) rightObjArr.push(obj);
    
            // 重置判断标识
            has = true;
        });
    
        // 返回符合条件的对象数组
        return rightObjArr;
    };

translatePigLatinString: 拉丁猪字符串转换

  • 分析可能的两种情况(主要使用到的方法:split, findIndex, splice, join)

    1. 如果字符串第一个字符是元音字符,则直接在字符串最后面追加“way”返回;
    2. 如果字符串第一个字符是非元音字符,则找到字符串中第一个元音字符的位置,根据这个位置将其前面的所有非元音字符用splice删除,并将删除的字符(字符串),追加到字符串结尾,然后再追加”ay”,组成新的字符串返回;
    function translatePigLatinString ( str ) {
    
        if ( !str ) return;
    
        // 如果字符串第一个字符就是元音字符,直接在后面追加"way"
        if ( tools.isVowel(str[0]) ) return str + "way";
    
        var strArr  = str.split(""),
            preStr  = "",
            index   = -1;
    
        /**
         * findIndex: 用来查找数组中符合callback条件的元素的索引
         * find: 返回的是元素本身
         */
        index = strArr.findIndex(function ( ele, index ) {
            if ( tools.isVowel(ele) ) return index;
        });
    
        // 取出最前面非元音字符的字符
        preStr = strArr.splice( 0, index ).join( "" );
    
        strArr.push( preStr );
    
        return strArr.join( "" ) + "ay";
    }

findVacantCharsFromString : 从一串连续且有序的字符串中找出空缺的字符,返回所有空缺字符组成的数组

  • 思路:

    1. 将字符串变成数组,用split;
    2. 用reduce去遍历该数组;
    3. reduce中,用上一个元素转码 + 1 和下一个比较,相等表示挨着不保存,不相等表示中间空了字符,保存该字符(即上一个字符转码后+1);
    4. 把步骤3中找到的空缺字符保存到数组中,最后处理完,得到的数组就是字符串中空缺的字符组成的数组。
  • 缺陷(有待完成):

    1. 尚不能找出中间空缺两个及两个字符以上的情况,如:”abcdgh”该字符’d’和’g’之间相差两个字符的情况没法找出来;
    2. 传进来的字符串不一定是有顺序的,需要进行排序处理。
    /**
     * 4. 找出字符串中不连续的空缺字符
     * 比如:"abce"中间漏掉了个"d"字符串
     * @param  {String} str 目标字符串
     * @return {数组}     空缺字符组成的新数组,如果传入的字符串都是连续的则返回"undefined"
     *
     * PS:目前只支持中间空缺一个字符的情况(如:"abcf"中间空缺"de"两个的还不支持)
     */
    function findVacantCharsFromString ( str ) {
    
        if ( !str ) return;
    
        // 1. 将字符串变成数组,用split
        // 2. 用reduce去遍历该数组
        // 3. reduce中,用上一个元素转码 + 1 和下一个比较,相等表示挨着不保存
        //    不相等表示中间空了字符,保存该字符(即上一个字符转码后+1)
        // 4. 把步骤3中找到的空缺字符保存到数组中,最后处理完,
        //    得到的数组就是字符串中空缺的字符组成的数组
    
        var strArr      = str.split(""),
            resArr      = [];
    
        // 使用到的原生API
        // string.charCodeAt(index) : 将字符串中索引指定位置的字符转成ASC编码
        // String.fromCharCode(num1[, num2 ...]) : 将ASC编码转成字符,
        //  >   支持多个同时转,返回转成功之后字符组成的字符串;
        //  
        //  PS: 注意编码转字符的方法,是String的类方法
        strArr.reduce(function ( preV, currV, currIndex, array ) {
            var preVCode    = preV.charCodeAt(0),
                currVCode   = currV.charCodeAt(0);
    
            if ( preVCode + 1 != currVCode ) {
    
                // 先从编码转成字符,保存到空缺字符数组中
                resArr.push( String.fromCharCode( preVCode + 1 ) );
            } 
    
            // 因为reduce的返回值即下一个preV的值
            // 所以这里将当前的值currV保存到preV
            return currV;
        });
    
        return resArr.length > 0 ? resArr : "undefined";
    }
  • 有蛮久学习了,最近一直在调整作息,之前一直很晚在看书啊,写点代码什么的,但是发觉第二天状态非常不好,上班经常瞌睡走神,所以这段时间把作息调整了过来^_^!!! 现在啊,回去浪一下,翻翻书十一点也就睡了,可是为啥早上还是那么贪睡 - -!!! 不过上班精神多了,写起代码来,解起问题来效率也大大提高不少。也决定把晚上时间多休息休息,周末好好学习。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若叶岂知秋vip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值