你如何sorting在多列上的数组?
我有一个multidimensional array。 主数组是一个数组
[publicationID][publication_name][ownderID][owner_name]
我想要做的是按owner_name
然后由publication_name
sorting数组。 我知道在JavaScript中你有Array.sort()
,你可以把自定义函数,在我的情况下,我有:
function mysortfunction(a, b) { var x = a[3].toLowerCase(); var y = b[3].toLowerCase(); return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }
这只是sorting上一列,即owner_name罚款,但如何修改它在owner_name
,然后publication_name
sorting?
如果所有者名称不同,请按照它们sorting。 否则,使用发布者名称作为tiebreaker。
function mysortfunction(a, b) { var o1 = a[3].toLowerCase(); var o2 = b[3].toLowerCase(); var p1 = a[1].toLowerCase(); var p2 = b[1].toLowerCase(); if (o1 < o2) return -1; if (o1 > o2) return 1; if (p1 < p2) return -1; if (p1 > p2) return 1; return 0; }
我想你在找什么是然后BJ.JS: https : //github.com/Teun/thenBy.js
它允许你使用标准的Array.sort,但是使用firstBy().thenBy().thenBy()
风格。
在这里可以看到一个例子 。
遇到需要做SQL样式混合asc和desc对象数组按键sorting。
上面的肯尼贝克的解决scheme帮助我得到这个:
Array.prototype.keySort = function(keys) { keys = keys || {}; // via // https://stackoverflow.com/questions/5223/length-of-javascript-object-ie-associative-array var obLen = function(obj) { var size = 0, key; for (key in obj) { if (obj.hasOwnProperty(key)) size++; } return size; }; // avoiding using Object.keys because I guess did it have IE8 issues? // else var obIx = function(obj, ix){ return Object.keys(obj)[ix]; } or // whatever var obIx = function(obj, ix) { var size = 0, key; for (key in obj) { if (obj.hasOwnProperty(key)) { if (size == ix) return key; size++; } } return false; }; var keySort = function(a, b, d) { d = d !== null ? d : 1; // a = a.toLowerCase(); // this breaks numbers // b = b.toLowerCase(); if (a == b) return 0; return a > b ? 1 * d : -1 * d; }; var KL = obLen(keys); if (!KL) return this.sort(keySort); for ( var k in keys) { // asc unless desc or skip keys[k] = keys[k] == 'desc' || keys[k] == -1 ? -1 : (keys[k] == 'skip' || keys[k] === 0 ? 0 : 1); } this.sort(function(a, b) { var sorted = 0, ix = 0; while (sorted === 0 && ix < KL) { var k = obIx(keys, ix); if (k) { var dir = keys[k]; sorted = keySort(a[k], b[k], dir); ix++; } } return sorted; }); return this; };
样本用法:
var obja = [ {USER:"bob", SCORE:2000, TIME:32, AGE:16, COUNTRY:"US"}, {USER:"jane", SCORE:4000, TIME:35, AGE:16, COUNTRY:"DE"}, {USER:"tim", SCORE:1000, TIME:30, AGE:17, COUNTRY:"UK"}, {USER:"mary", SCORE:1500, TIME:31, AGE:19, COUNTRY:"PL"}, {USER:"joe", SCORE:2500, TIME:33, AGE:18, COUNTRY:"US"}, {USER:"sally", SCORE:2000, TIME:30, AGE:16, COUNTRY:"CA"}, {USER:"yuri", SCORE:3000, TIME:34, AGE:19, COUNTRY:"RU"}, {USER:"anita", SCORE:2500, TIME:32, AGE:17, COUNTRY:"LV"}, {USER:"mark", SCORE:2000, TIME:30, AGE:18, COUNTRY:"DE"}, {USER:"amy", SCORE:1500, TIME:29, AGE:19, COUNTRY:"UK"} ]; var sorto = { SCORE:"desc",TIME:"asc", AGE:"asc" }; obja.keySort(sorto);
产生以下结果:
0: { USER: jane; SCORE: 4000; TIME: 35; AGE: 16; COUNTRY: DE; } 1: { USER: yuri; SCORE: 3000; TIME: 34; AGE: 19; COUNTRY: RU; } 2: { USER: anita; SCORE: 2500; TIME: 32; AGE: 17; COUNTRY: LV; } 3: { USER: joe; SCORE: 2500; TIME: 33; AGE: 18; COUNTRY: US; } 4: { USER: sally; SCORE: 2000; TIME: 30; AGE: 16; COUNTRY: CA; } 5: { USER: mark; SCORE: 2000; TIME: 30; AGE: 18; COUNTRY: DE; } 6: { USER: bob; SCORE: 2000; TIME: 32; AGE: 16; COUNTRY: US; } 7: { USER: amy; SCORE: 1500; TIME: 29; AGE: 19; COUNTRY: UK; } 8: { USER: mary; SCORE: 1500; TIME: 31; AGE: 19; COUNTRY: PL; } 9: { USER: tim; SCORE: 1000; TIME: 30; AGE: 17; COUNTRY: UK; } keySort: { }
(从这里使用打印function)
这里是一个jsbin的例子 。
编辑: 清理并在github上发布为mksort.js 。
这对所有大小的alphasorting都很方便。 按顺序传递你想要sorting的索引,作为参数。
Array.prototype.deepSortAlpha= function(){ var itm, L=arguments.length, order=arguments; var alphaSort= function(a, b){ a= a.toLowerCase(); b= b.toLowerCase(); if(a== b) return 0; return a> b? 1:-1; } if(!L) return this.sort(alphaSort); this.sort(function(a, b){ var tem= 0, indx=0; while(tem==0 && indx<L){ itm=order[indx]; tem= alphaSort(a[itm], b[itm]); indx+=1; } return tem; }); return this; } var arr= [[ "Nilesh","Karmshil"], ["Pranjal","Deka"], ["Susants","Ghosh"], ["Shiv","Shankar"], ["Javid","Ghosh"], ["Shaher","Banu"], ["Javid","Rashid"]]; arr.deepSortAlpha(1,0);
你可以将这两个variables连接成一个sortkey并用于比较。
list.sort(function(a,b){ var aCat = a.var1 + a.var2; var bCat = b.var1 + b.var2; return (aCat > bCat ? 1 : aCat < bCat ? -1 : 0); });
sortingstring的许多字段的一个好方法是使用toLocaleCompare
和布尔运算符||
。
就像是:
// Sorting record releases by name and then by title. releases.sort((oldRelease, newRelease) => { const compareName = oldRelease.name.localeCompare(newRelease.name); const compareTitle = oldRelease.title.localeCompare(newRelease.title); return compareName || compareTitle; })
如果你想sorting更多的领域,你可以简单地链接他们更多的布尔运算符返回语句。
我build议使用内置的比较器,并用逻辑或||
来链接想要的sorting顺序 。
function customSort(a, b) { return a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]); }
工作示例:
var array = [ [0, 'Aluminium', 0, 'Francis'], [1, 'Argon', 1, 'Ada'], [2, 'Brom', 2, 'John'], [3, 'Cadmium', 3, 'Marie'], [4, 'Fluor', 3, 'Marie'], [5, 'Gold', 1, 'Ada'], [6, 'Kupfer', 4, 'Ines'], [7, 'Krypton', 4, 'Joe'], [8, 'Sauerstoff', 3, 'Marie'], [9, 'Zink', 5, 'Max'] ]; array.sort(function (a, b) { return a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]); }); document.write('<pre>'); array.forEach(function (a) { document.write(JSON.stringify(a) + '<br>'); });
我正在使用ng-grid
,需要对从API返回的logging数组进行多列sorting,所以我想出了这个漂亮的dynamic多重sorting函数。
首先, ng-grid
为“ngGridSorted”激发一个“事件”,并将这个结构传递回来,描述这种sorting:
sortData = { columns: DOM Element, directions: [], //Array of string values desc or asc. Each index relating to the same index of fields fields: [], //Array of string values };
所以我build立了一个dynamic生成sortData
函数,如上图所示( 不要被滚动条吓倒!只有50行左右!另外,对于这个斜坡我也很抱歉,水平滚动条! ):
function SortingFunction(sortData) { this.sortData = sortData; this.sort = function(a, b) { var retval = 0; if(this.sortData.fields.length) { var i = 0; /* Determine if there is a column that both entities (a and b) have that are not exactly equal. The first one that we find will be the column we sort on. If a valid column is not located, then we will return 0 (equal). */ while( ( !a.hasOwnProperty(this.sortData.fields[i]) || !b.hasOwnProperty(this.sortData.fields[i]) || (a.hasOwnProperty(this.sortData.fields[i]) && b.hasOwnProperty(this.sortData.fields[i]) && a[this.sortData.fields[i]] === b[this.sortData.fields[i]]) ) && i < this.sortData.fields.length){ i++; } if(i < this.sortData.fields.length) { /* A valid column was located for both entities in the SortData. Now perform the sort. */ if(this.sortData.directions && i < this.sortData.directions.length && this.sortData.directions[i] === 'desc') { if(a[this.sortData.fields[i]] > b[this.sortData.fields[i]]) retval = -1; else if(a[this.sortData.fields[i]] < b[this.sortData.fields[i]]) retval = 1; } else { if(a[this.sortData.fields[i]] < b[this.sortData.fields[i]]) retval = -1; else if(a[this.sortData.fields[i]] > b[this.sortData.fields[i]]) retval = 1; } } } return retval; }.bind(this); }
然后,我将API( results
)的结果sorting如下:
results.sort(new SortingFunction(sortData).sort);
我希望有人像我一样喜欢这个解决scheme! 谢谢!
function multiSort() { var args =$.makeArray( arguments ), sortOrder=1, prop='', aa='', b=''; return function (a, b) { for (var i=0; i<args.length; i++){ if(args[i][0]==='-'){ prop=args[i].substr(1) sortOrder=-1 } else{sortOrder=1; prop=args[i]} aa = a[prop].toLowerCase() bb = b[prop].toLowerCase() if (aa < bb) return -1 * sortOrder; if (aa > bb) return 1 * sortOrder; } return 0 } } empArray.sort(multiSort( 'lastname','firstname')) Reverse with '-lastname'