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>');
});

数组排序,字符串math,replace练习的更多相关文章

  1. JavaScript 字符串 & Math & Date

    字符串 字符串就是零个或多个排在一起的字符,放在单引号或双引号之中. 'abc' "abc" 单引号字符串的内部,可以使用双引号.双引号字符串的内部,可以使用单引号. 'key=& ...

  2. js中字符串的replace方法区分单双引号

    今天遇到一问题,js文件中调用字符串的replace方法,不起作用. 后来排查可能觉得replace("<option  value='1'>admin</option&g ...

  3. 浅谈JavaScript的字符串的replace方法

    JavaScript字符串提供了一个replace方法.replace方法可以接受两个参数:第一个参数可以使RegExp对象或者一个字符串,第二个参数可以是一个字符串或者一个函数.如果第一个参数是字符 ...

  4. 字符串替换replace方法

    字符串替换replace方法: http://www.w3school.com.cn/jsref/jsref_replace.asp http://www.cnblogs.com/skywang/ar ...

  5. js常用的数组,,字符串,,Math..正则方法

    数组 slice[start,end] 返回从原数组中指定开始下标到结束下标之间的项目组成新数组(不会影响原数组) splice() 1.删除功能:2个参数 , 起始位置 , 删除的项目 2.插入功能 ...

  6. 数组/字符串/ Math / 方法示例

    数组 Array concat  数组的合并 <script> var north = ["北京","上海","深圳"]; va ...

  7. 字符串的replace()方法隐藏着什么不可告人秘密?

    最近在做JS算法项目时发现一个令我匪夷所思的问题, 这里想记录一下问题. 首先介绍一下字符串replace()方法的基本用法. replace() 方法使用一个替换值(replacement)替换掉一 ...

  8. C# 字符串替换Replace

    C# 中的石strA.Replace(strB,strC)函数可以实现将strA中的strB替换为strC. 但是容易出错的地方是,这并不是就直接替换好了,此函数的返回值才是替换好的字符串,所以还要要 ...

  9. JavaScript——关于字符串的replace函数中的function函数的参数

    <!DOCTYPE> <html> <head> </head> <body> <script type="text/jav ...

随机推荐

  1. lintcode:字符串置换

    题目 给定两个字符串,请设计一个方法来判定其中一个字符串是否为另一个字符串的置换. 置换的意思是,通过改变顺序可以使得两个字符串相等. 样例 "abc" 为 "cba&q ...

  2. libevent功能使用简介

    http://blog.csdn.net/happyanger6/article/details/7272324 1. 介绍 libevent是一个用来开发可扩展的网络服务器的事件通知函数库.当一个文 ...

  3. Mysql笔记——DDL

    数据库模式定义语言DDL(Data Definition Language),是用于描述数据库中要存储的现实世界实体的语言.一个数据库模式包含该数据库中所有实体的描述定义.   =========== ...

  4. How to configure Spring facet in IntelliJ IDEA

    遇到了这个问题,稀里糊涂的就给搞定了,在stackoverfolw上看到了相同的问题,直接拷贝下来吧 Spring Configuration Check Unmapped Spring config ...

  5. wrong number of arguments,java方法反射时数组参数的坑

    java方法中只有一个参数是数组,反射的时候我们不能想当然的传歌数组进去,传数组进去的时候表示多个参数. 两个数组不是一个意思啊. 我们应该把数组转为objet,这样才表示一个参数. import j ...

  6. linux select

    man select: #include <sys/select.h> #include <sys/time.h> int select(int nfds, fd_set *r ...

  7. USACO Section 2.2: Preface Numbering

    搬了leetcode的代码 /* ID: yingzho1 LANG: C++ TASK: preface */ #include <iostream> #include <fstr ...

  8. eclipse中servers(服务器)的配置

    eclipse中servers(服务器)的配置 使用eclipse+tomcat时,很多人喜欢安装tomcat插件,以便一键启动tomcat,但我不喜欢给eclipse安装一些非必须的插件,而ecli ...

  9. android:screenOrientation的说明 固定屏幕显示方向

    Activity在屏幕当中显示的方向.属性值可以是下表中列出的一个值: "unspecified" 默认值,由系统来选择方向.它的使用策略,以及由于选择时特定的上下文环境,可能会因 ...

  10. powerdesigner 15 如何导出sql schema

    PowerDesigner导出所有SQL脚本 操作:Database=>Generate Database PowerDesigner怎么导出建表sql脚本 1 按照数据库类型,切换数据库. D ...