多条件排序可能有很多种思路,效率也各不相同,我的方法可能只适合自己用,毕竟目的是为了实现功能,所以采用了最笨的方法,不过效果还是很理想的,经过多次测试,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. str*函数和大小端判断

    #include <stdio.h> #include <assert.h> size_t mstrlen(const char *s) { assert(s != NULL) ...

  2. [九度OJ]1137.浮点数加法

    原题链接:http://ac.jobdu.com/problem.php?pid=1137 题目描述: 求2个浮点数相加的和题目中输入输出中出现浮点数都有如下的形式:P1P2...Pi.Q1Q2... ...

  3. Oracle10g/11g 在SUSE/RHEL上的安装与配置

    在过去对众多项目的支撑过程中,Oracle作为首选数据库,其安装与配置过程成了重复性最多的工作之一.在此,我进行了总结,并分享出来,希望能对大家有所帮助.随着Oracle版本的提升,从9i -> ...

  4. rx tx

  5. 通过一张简单的图,让你彻底地搞懂JS的==运算

    大家知道,JavaScript中的==是一种比较复杂运算,它的运算规则很奇怪,很容易让人犯错,从而成为JavaScript中“最糟糕的特性”之一. 在仔细阅读ECMAScript规范的基础上,我画了一 ...

  6. eclipse中的maven配置

    1.下载最新版eclipse,包含maven版本 2.配置maven本地仓库(修改settings.xml)

  7. windows蓝屏代码大全及常见蓝屏解决方案

    对于以下的代码查询建议使用ctrl+F查询,而且很多蓝屏与黑屏的问题多是最近操作引起的,例如更新驱动,安装新的硬件.软件--把相关的配置调到最近的正常状况大多可以解决,确实不行时方可考虑重装系统,解决 ...

  8. Spring Framework 5.0.0.M3中文文档 翻译记录 introduction

    翻译自: http://docs.spring.io/spring/docs/5.0.0.M3/spring-framework-reference/htmlsingle/#spring.tld.ha ...

  9. C#基础知识学习手记1

    这篇随笔主要用来记录我在C#学习过程做的笔记,算作是一门课程中的小知识点吧. 1. 变量和表达式                         1.1 如何在输出带有引号(英文双引号.英文单引号)以 ...

  10. 【16】成对使用new和delete时要采取相同形式

    简而言之,new时不带[],delete时也不带[]:new时带[],delete时也要带[].如果不匹配,要么造成多销毁对象,导致未定义行为:要么导致少销毁对象,导致内存泄漏.