多条件排序可能有很多种思路,效率也各不相同,我的方法可能只适合自己用,毕竟目的是为了实现功能,所以采用了最笨的方法,不过效果还是很理想的,经过多次测试,6列1000行数据,平均排序时间大约是:28ms。

具体实现代码如下:

    function isArr(data) {
return ({}).toString.call(data) == '[object Array]';
} function getIndex(arr) {
var i = 0,
len = arr.length
keys = [];
while (i < len) {
keys.push(i++);
}
return keys;
} // 检测数组最大维数,非数组则返回-1,如果有num则表明检测数组是否为指定维数
function checkArrDim(arr, num) {
var dimension = -1,
num = parseInt(num),
isCheck = isNaN(num) ? false : true,
dm = [0], i, len, mx;
if (isArr(arr) && (len = arr.length) > 0) {
dimension = 1; // 任何一个数组,只要有数据,至少是个1维
for (i = 0; i < len; i++) {
dm.push(checkArrDim(arr[i])); // 递归获取每个元素的维数,如果dm数组中全是-1则说明arr是1维数组
}
dimension = (mx = Math.max.apply(null, dm)) === -1 ? dimension : dimension + mx;
}
// 如果dm数组长度 <= 1则说明arr压根不是数组,或者是空数组
// 当dm数组长度 > 1,且dimension == 1,说明arr是1维数组
// 或者dimension <> 1,因为dm默认填充1个0,只要所有元素的和 / dm去掉0后的长度 == num - 1,即说明是n维数组
return isCheck ? (dm.length > 1 ? (dimension == 1 && num == 1) || eval(dm.join('+')) / (dm.length - 1) == num - 1 : false) : dimension;
} function msort(arr, field, order) {
if (!checkArrDim(arr, 2) || !checkArrDim(field, 1) || !checkArrDim(order, 1)) {
return ;
}
var key, tmp, val, sa, sk, pre;
var i, ilen, j, jlen, k, klen, m, mlen;
var range = [], rng;
// 按已排序数组的索引数组排序待定数组
var sortFromKey = function (data, key) {
var tmp = [], i, j, len;
for (i = 0, len = key.length; i < len; i++) {
tmp.push(data[key[i]]);
}
for (j = 0; j < len; j++) {
data[j] = tmp[j];
}
};
// 多条件排序
for (i = 0, ilen = field.length; i < ilen; i++) {
tmp = arr[field[i]];
if (i === 0) {
// 第1次排序,直接对当前字段所在数组排序
key = getIndex(tmp);
tmp.mergeSort(key, order[i]);
range.push([0, tmp.length - 1]);
} else {
// 如果有第2个及以上的条件,则均以前1个条件为参照,获取前1个已排序数组
// 内每一组相同元素的区间,对该区间内元素赋值到临时数组并排序,并获取排序
// 索引,最终拼接在一起这个拼接在一起的新的索引数组即是其它所有数组排序的参照,
// 经过上述循环执行,即可完成多条件排序
// ↓核心工作前的初始工作
pre = arr[field[i - 1]]; // 前1个已排序数组
val = pre[0];
sa = [tmp[0]];
sk = [0];
key = [];
rng = [];
// 本排序核心工作即整理已排序数组的同值区间,此区间是当前待排序数组多个排序区间的唯一参照
for (k = 0, klen = range.length; k < klen; k++) {
for (m = range[k][0] + 1, mlen = range[k][1] + 1; m <= mlen; m++) { // 注意此处条件表达式,需要额外执行一次排序和初始化
if (val === pre[m] && m !== mlen) { // 无论区间多小,哪怕只有1个元素,当m = mlen时必须执行排序和下一步的初始准备
sa.push(tmp[m]);
sk.push(m);
} else {
rng = rng.concat([[sk[0], sk[sk.length - 1]]]);
sa.mergeSort(sk, order[i]); // 主要是为了获取sk
key = key.concat(sk);
val = pre[m];
sa = [tmp[m]];
sk = [m];
}
}
}
range = rng; // 获取整理后的待排序区间
sortFromKey(tmp, key); // 对当前数组排序
}
// 经过前面的过程,一个条件已经排序完成,并且获得排序后的原索引(数组)
// 然后对除了当前字段数组外的其它所有数组按已排序索引重新排列
for (j = 0, jlen = arr.length; j < jlen; j++) {
if (j == field[i]) {
continue;
}
sortFromKey(arr[j], key);
}
}
}

其中用到数组mergeSort()是自己定义到Array.prototype的方法,链接地址:Javascript-归并排序

Javascript 迭代法实现数组多条件排序的更多相关文章

  1. js 数组sort, 多条件排序。

    Array.sort(); sort()方法可以传入一个函数作为参数,然后依据该函数的逻辑,进行数组的排序. 一般用法:(数组元素从小大进行排序) var a = [9, 6, 5, 7, 11, 5 ...

  2. javascript:算法之数组sort排序

    数组sort排序 sort比较次数,sort用法,sort常用 描述 方法sort()将在原数组上对数组元素进行排序,即排序时不创建新的数组副本.如果调用方法sort()时没有使用参数,将按字母顺序( ...

  3. JavaScript中对数组的排序

    将下列对象数组,通过工资属性,由高到低排序 var BaiduUsers = [], WechatUsers = []; var User = function(id, name, phone, ge ...

  4. javascript中关于数组的一些鄙视题

    一.判断一个数组中是否有相同的元素 /* * 判断数组中是否有相同的元素的代码 */ // 方案一 function isRepeat1(arrs) { if(arrs.length > 0) ...

  5. JavaScript中的数组详解

    JavaScript中的数组 一.数组的定义 数组是值的有序集合,或者说数组都是数据的有序列表. 二.创建数组 [字面量形式] 1.空数组 var arr=[]; 2.带有元素的数组 var arr= ...

  6. javascript中的数组操作

    1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限, ...

  7. JavaScript高级特性-数组

    1. JavaScript中的数组 在C++.Java中,数组是一种高效的数据结构,随机访问性能特别好,但是局限性也特别明显,就是数组中存放的数据必须是同一类型的,而在JavaScript中,数组中的 ...

  8. JavaScript中Array(数组) 对象

    JavaScript中Array 对象 JavaScript中创建数组有两种方式 (一)使用直接量表示法: var arr4 = []; //创建一个空数组var arr5 = [20]; // 创建 ...

  9. JavaScript中操作数组的方法

    JavaScript Array 对象 对数组操作的方法分为两种 一种是会改变原始数组的变异方法,还有一种是不会改变原始数组的非变异方法. 总结 巧记 Push() 尾部添加 pop() 尾部删除 U ...

随机推荐

  1. JUnit学习总结

    Junit简介: Junit最初是由Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),为单元测试(Unit Test) ...

  2. 初探WebService

    写博客也是一件非常费时的事儿啊,之前配置服务器和客户端的Oracle数据库搞了很久,搞定之后懒的记录,现在想想如果让我再配一次,估计又要花很长时间了. 所以把做过的东西整理整理记录下来还是很有必要的, ...

  3. 计算智能 Computational Intelligence,CI

    计算智能(Computational Intelligence,CI)是借助自然界(生物界)规律的启示,根据其规律,设计出求解问题的算法.智能计算只是一种经验化的计算机思考性程序. 计算智能算法主要包 ...

  4. 关于Eclispse连接Mysql的Jdbc

    1.在Eclipse中新建Java工程 2.引入JDBC库(在bulid path 的extenrnal里) 3. 1)导入sql包(import java.sql.*) 2)加载(注册)mysql ...

  5. CentOS搭建VSFTP

    1.先看看有没有安装 rpm -qa | grep vsftpd 如果没有提示,说明没有安装.接下来,我们安装一个ftp. 2.yum安装vsftpd: yum -y install vsftpd 安 ...

  6. PC-老鸟装机

    老鸟装机 一.硬件安装莫疏忽   1>安装硬盘有讲究     1.单硬盘+单光驱       IDE1----硬盘(Mastet接口)       IDE2----光驱(Mastet接口)    ...

  7. javascript-智能社-JS基础B笔记

    运算符 算术:+ 加.- 减.* 乘./ 除.% 取模(也叫取余) 余数就是不能整除的多出来的那部分 比如说 23除以5 等于4.6   保留整数4舍弃小数.6  然后用保留的整数4乘以5等20  最 ...

  8. unity3d 获取相机视口四个角的坐标

    功能:如标题所示,主要考虑用来做3d Plane的自适应屏幕 /// <summary> /// 获取指定距离下相机视口四个角的坐标 /// </summary> /// &l ...

  9. CopyU!v2.2 增加对设备信息的识别

    更新版本的CopyU!v2.2已经完成大部分功能的设计,主打升级功能“设备信息识别”已经基本完成,现在放上测试截图:

  10. POJ 1330 Nearest Common Ancestors(Tree)

    题目:Nearest Common Ancestors 根据输入建立树,然后求2个结点的最近共同祖先. 注意几点: (1)记录每个结点的父亲,比较层级时要用: (2)记录层级: (3)记录每个结点的孩 ...