zoukankan      html  css  js  c++  java
  • 数组排序,字符串math,replace练习

    1. 关于数组排序

        排序一直是程序设计中的热门话题。在js中,数组有个sort()方法。在不传参数默认情况下,数组的sort()方法原理是:对数每项调用toString()方法,比较字符串按升序排序数组。看下面的例子。

    var arrA = [null, undefined, 3, 2, 5, 21, {toString:function() {
        return 1;
    }, p:'hello'}];
    var arrB = [undefined, null, 3, 2, 5, 21,{toString:function() {
        return 1;
    }, p: 'hello'}];    
    var arrC = [null, undefined, 3, 2, 21, {toString:function() {
        return 1;
    }, p:'hello'},
    {a:1},
    {toString:function(){return 'p'}},
    {toString:function(){return 'oa'}},
    {toString:function(){return 'p'}},
    {toString:function(){return 'v'}}, 'u', 'v', 'nukk','nulk'
    ];
    
    arrA.sort();//结果是:[Object, 2, 21, 3, 5, null, undefined]
    arrB.sort();//结果是:[Object, 2, 21, 3, 5, null, undefined]
    arrA.sort()[0].p;//hello
    arrC.sort();

    上面的例子说明:

    a. sort()方法不传比较函数时,的确是对每项调用了toString()方法[对null应该是使用String(null)]转换成字符串再进行升序排序的

    b. undefined不会参与排序,直接放最后面

    当要使用其它标准对数组进行排序时,就要传入一个比较函数作为参数。原理及执行过程没有弄清楚(有知道的请告诉下),但得到如下结论:

    var arrD = [3, 5, 1, 8, 10];
    
    console.log(arrD.sort(compare));
    
    function compare(v1, v2) {
        var a = v1;
        var b = v2;
        console.log('v1='+v1 + '||'+ 'v2='+v2);
        //return v1 - v2; //升序
        //return v2 - v1;//降序
        //return -1;  //原样输出
        //return 0; //原样输出
        //return 1; //反顺输出
    }

    下面是一个实际Demo:

    /**
     * 为数组实现一个排序方法,能够num、string、date、character和object的排序,
     * 对object类型排序时,按照某个属性排序。只考虑数组中存放都是相同类型的数据
     * @param {Boolean} order 为true表示升序,false表示降序
     * @param {String} key 对象的键值
     */
    Array.prototype.sameTypeSort = function(order, key) {
        var type = type(this[0]);
        var ret = [], i = 0, temp, tempArr = [];
        order = order ? true : false;
        switch(type) {
            case 'string':
                ret = this.sort();//升序
                break;
            case 'number':
                ret = this.sort(ascending);
                break;
            case 'date':
                while(temp = this[i]) {
                    tempArr.push(temp.getTime());
                    i++;
                }
                tempArr.sort(ascending);
                break;
            default :
                while(i < this.length) {
                    tempArr.push(this[i][key]);
                    i++;
                }
                tempArr = tempArr.sameTypeSort(true);
        }
    
    
        //如果是时间,对象还要将还原成排序前的值
        if(type === 'date') {
            i = 0;
            while(temp = tempArr[i]) {
                ret.push(new Date(temp));
                i++;
            }
        }
    
        if(type === 'object') {
            i = 0;
            while(temp = tempArr[i]) {
                for(var start = 0, curObj, value; curObj = this[start]; start++) {
                    value = curObj[key];
                    if(value === temp) {
                        ret.push(curObj);
                        break;
                    }
                }
                i++;
            }
        }
    
        return order ? ret : ret.reverse();
    
        function type(target) {
            return ({}).toString.call(target).slice(8, -1).toLocaleLowerCase();
        }
        function ascending(v1, v2) {
            return v1 - v2;
        }
    };

    下面是通过的Qunit的测试代码:

    test( "数值排序", function() {
        var arr = [1,11,2,22,3,33,-5,-55, 0];
        var upOrder = [-55, -5, 0, 1,2,3,11,22, 33];
    
        propEqual(arr.sameTypeSort(true), upOrder, 'pass');
        propEqual(arr.sameTypeSort(false), upOrder.reverse(), 'pass');
    });
    
    test( "字符串排序", function() {
        var arr = ['aa', 'ac', 'ab', 'bc', 'ba', 'acd'];
        var upOrder = ['aa', 'ab', 'ac', 'acd', 'ba', 'bc'];
    
        propEqual(arr.sameTypeSort(true), upOrder, 'pass');
        propEqual(arr.sameTypeSort(false), upOrder.reverse(), 'pass');
    });
    
    test( "时间排序", function() {
        var arr = [new Date('2014/06/16 0:0:0'), new Date('2014/06/12 0:0:0'), new Date('2014/06/14 0:0:0')];
    
        strictEqual(arr.sameTypeSort(true)[0].getTime(), arr[1].getTime());
        strictEqual(arr.sameTypeSort(false)[0].getTime(), arr[0].getTime());
    });
    
    test( "对象排序", function() {
        var arr = [
            {key:5, f: 'x'},
            {key:2, f:'y'},
            {key:6, f:'z'}
        ];
    
        strictEqual(arr.sameTypeSort(true, 'key')[0].f, 'y');
        strictEqual(arr.sameTypeSort(false, 'key')[0].f,'z');
        console.log(arr.sameTypeSort(true, 'key'));
        console.log(arr.sameTypeSort(false, 'key'));
    });

    2. match,replace函数练习

    a. 价格千分

    /**
     * 在整数部分对费用进行千分。一开始想用正则来做,但实现过程中发现各种问题,最后代码变成下面的样子了
     * @param {String} feeStr 有效的费用数值字符串
     * @returns {String} 进行了千分格式化后的字符串
     */
    function splitFee(feeStr) {
        var ret, leftCtx, rightCtx;
    
        ponintPos = feeStr.indexOf('.');
        if(ponintPos !== -1) {
            leftCtx = feeStr.substring(0, ponintPos);
            rightCtx = feeStr.substring(ponintPos+1);
        } else {
            leftCtx = feeStr;
            rightCtx = '';
        }
    
        /*match = feeStr.match(/./);
        leftCtx = RegExp.leftContext;//整数部分
        rightCtx = RegExp.rightContext;  使用正则会有一个Bug,若后面match匹配失败,后面的rightCtx始终会保存前次匹配的值*/
        leftCtx = leftCtx ? leftCtx : feeStr;
        rightCtx = rightCtx ? '.'+rightCtx : '';
    
        ret = (leftCtx.split('').reverse().join('').replace(/(d{3})/g, function(m, ms, offset, targetStr) {
            return m + ','
        }).split('').reverse().join('')+rightCtx).replace(/^\,/,'');
    
        return ret;
    }

    通过的Qunit测试代码

    test( "replace, match练习:数值字符串千分", function() {
        //对整数部分进行千分
        var fee1 = '1747136.51';
        var fee2 = '277136.52';
        var fee3 = '37136.53';
        var fee4 = '47136';
        var fee5 = '136';
    
        strictEqual(splitFee(fee1), '1,747,136.51');
        strictEqual(splitFee(fee2), '277,136.52');
        strictEqual(splitFee(fee3), '37,136.53');
        strictEqual(splitFee(fee4), '47,136');
        strictEqual(splitFee(fee5), '136');
    });

    b. 交换包含两个单词的字符串

    /**
     * 交换单词字符串中的两个单词
     * @param str
     * @returns {String}
     */
    function swapTwoWords(str) {
        return str.replace(/(w+)s(w+)/, '$2 $1');
        //return str.split(' ').reverse().join(' '); 使用数组
    }
    
    //Qunit测试
    test( "replace练习:交换单词", function() {
        var str = 'hello world';
    
        strictEqual(swapTwoWords(str), 'world hello');
    });

    c. 字符串模板替换方法

    /**
     * 字符串模板替换方法
     * @param {String} str
     * @param {Object} obj
     */
    function format(str, obj) {
        return str.replace(/({w+})/gm, function(m, ms, offset, targetStr) {
            return obj[m.substring(1, m.length - 1)];
        });
    }
    
    //Qunit测试
    test( "字符串模板format方法", function() {
        var str = '<div>{id}</div></div>{name}</div>';
    
        strictEqual(format(str, {id:100, name:'xyz', address:'cd'}), '<div>100</div></div>xyz</div>');
    });
  • 相关阅读:
    1105 Spiral Matrix (25 分)螺旋矩阵
    1089 Insert or Merge (25 分)
    1044 Shopping in Mars (25 分)二分查找
    1068 Find More Coins (30 分)记忆化搜索
    1133 Splitting A Linked List (25 分)
    1145 Hashing
    1147 Heaps (30 分)
    1098 Insertion or Heap Sort (25 分)
    自测-3 数组元素循环右移问题 (20 分)
    自测-1 打印沙漏 (20 分)
  • 原文地址:https://www.cnblogs.com/jagusOu/p/3789086.html
Copyright © 2011-2022 走看看