Javascript 如何在多个列上对数组进行排序?
我有一个多维数组。主数组是一个Javascript 如何在多个列上对数组进行排序?,javascript,algorithm,sorting,Javascript,Algorithm,Sorting,我有一个多维数组。主数组是一个 [publicationID][publication_name][ownderID][owner_name] 我试图做的是按owner\u name对数组排序,然后按publication\u name对数组排序。我知道在JavaScript中有Array.sort(),您可以将自定义函数放入其中,在我的例子中,我有: function mysortfunction(a, b) { var x = a[3].toLowerCase(); va
[publicationID][publication_name][ownderID][owner_name]
我试图做的是按owner\u name
对数组排序,然后按publication\u name
对数组排序。我知道在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));
}
函数mysortfunction(a,b){
var x=a[3]。toLowerCase();
var y=b[3]。toLowerCase();
回报率((xy)?1:0);
}
这对于仅对一列(即所有者名称)进行排序是很好的,但是如何修改它以对
owner\u name
进行排序,然后对publication\u name
?如果所有者名称不同,则按它们进行排序。否则,请使用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;
}
函数mysortfunction(a,b){
var o1=a[3].toLowerCase();
var o2=b[3]。toLowerCase();
var p1=a[1]。toLowerCase();
var p2=b[1]。toLowerCase();
如果(o1o2)返回1;
如果(p1p2)返回1;
返回0;
}
这对于各种尺寸的alpha类型都很方便。
将要按顺序排序的索引作为参数传递给它
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);
Array.prototype.deepSortAlpha=function(){
var itm,L=参数。长度,顺序=参数;
var alphaSort=函数(a,b){
a=a.toLowerCase();
b=b.toLowerCase();
如果(a==b)返回0;
返回a>b?1:-1;
}
如果(!L)返回此.sort(alphaSort);
this.sort(函数(a,b){
变量tem=0,indx=0;
而(tem==0&&indx遇到了一个需要执行SQL风格的混合asc和desc对象数组按键排序的问题
上述kennebec的解决方案帮助我做到了这一点:
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;
};
结果如下:
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: { }
(使用来自的打印功能)
编辑:。我想你要找的是thenBy.js:
它允许您使用标准的Array.sort,但使用firstBy().thenBy().thenBy()
样式
.您可以将这两个变量合并成一个排序键,并将其用于比较
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);
});
list.sort(函数(a,b){
var aCat=a.var1+a.var2;
var bCat=b.var1+b.var2;
返回(aCat>bCat-1:aCat
函数multiSort(){
var args=$.makeArray(参数),
sortOrder=1,prop='',aa='',b='';
返回函数(a,b){
对于(var i=0;i bb)返回1*排序器;
}
返回0
}
}
排序(多排序('lastname','firstname'))与'-lastname'相反
我建议使用内置比较器,并将所需的排序顺序与逻辑or链接起来
function customSort(a, b) {
return a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]);
}
工作示例:
var数组=[
[0,'Aluminal',0,'Francis'],
[1,‘氩’,1,‘Ada’],
[2,'Brom',2,'John'],
[3,'镉',3,'玛丽'],
[4,'Fluor',3,'Marie'],
[5,'Gold',1,'Ada'],
[6,'Kupfer',4,'Ines'],
[7,'氪',4,'乔'],
[8,'Sauerstoff',3,'Marie'],
[9,'Zink',5,'Max']
];
array.sort(函数(a,b){
返回a[3]。localeCompare(b[3])| | a[1]。localeCompare(b[1]);
});
文件。写(“”);
array.forEach(函数(a){
document.write(JSON.stringify(a)+'
');
})
我使用的是nggrid
,需要对API返回的记录数组进行多列排序,所以我想出了这个漂亮的动态多排序函数
首先,ng grid
为“ngGridSorted”触发一个“事件”,并将此结构传回,描述排序:
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);
}
因此,我构建了一个函数,该函数将根据如上所示的sortData
动态生成排序函数(不要被滚动条吓倒!它只有大约50行长!另外,我对slop感到抱歉。它阻止了水平滚动条!):
我希望其他人也像我一样喜欢这个解决方案!谢谢!对许多字符串字段进行排序的好方法是使用toLocaleCompare
和布尔运算符|
function customSort(a, b) {
return a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]);
}
比如:
- sort by the first column
- if equal, sort by the second
- if equal, sort by the third
- etc... nesting and nesting if-else
如果您想对更多字段进行排序,只需使用更多的布尔运算符将它们从返回语句中链接出来。我发现。这是一个简单、功能强大的小型多重排序库。我需要使用dynamics排序标准对一组对象进行排序:
const标准=['name','speciality']
常数数据=[
{姓名:'Mike',专业:'JS',年龄:22},
{姓名:'Tom',专业:'Java',年龄:30},
{姓名:'Mike',专业:'PHP',年龄:40},
{姓名:'Abby',专业:'Design',年龄:20},
]
常量排序=多排序(数据、标准)
console.log(已排序)
在显示某些虚拟DOM h函数组合输出的内存池块时,我遇到了类似的问题。基本上,我面临的问题与排序多标准数据(如来自世界各地玩家的评分结果)相同
我注意到多标准排序是:
// useful for chaining test
const decide = (test, other) => test === 0 ? other : test
如果你不在乎,你可能会很快在一个“如果”的地狱里失败…就像是地狱般的承诺
如果我们编写一个“谓词”函数来决定备选方案的哪一部分是否使用该谓词呢?谓词很简单:
const multisort = (s1, s2) => {
const bcs = -1 * byCountrySize(s1, s2) // -1 = desc
const ba = 1 *byAge(s1, s2)
const bgt = 0 * byGameType(s1, s2) // 0 = doesn't matter
const bs = 1 * byScore(s1, s2)
const bl = -1 * byLevel(s1, s2) // -1 = desc
// ... other weights and criterias
// array order matters !
return [bcs, ba, bgt, bs, bl].reduce((acc, val) => decide(val, acc), 0)
}
// invoke [].sort with custom sort...
scores.sort(multisort)
现在,在编写分类测试(按CountrySize、byAge、byGameType、byScore、byLevel…)之后,无论谁需要,您都可以对测试进行加权(1=asc、-1=desc、0=disable),将它们放入一个数组中,并应用如下减少的“决定”函数:
t.sort( (a,b)=> a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]) );
瞧!由你来定义你自己的标准/重量/顺序…但你明白了。希望这有帮助
编辑:
*确保每列上都有一个总排序顺序
*请注意,列和顺序之间没有依赖关系,也没有循环依赖关系
如果不是,排序可能不稳定!请尝试以下方法:
设t=[
//[出版物ID、出版物名称、所有者ID、所有者名称]
[1,'ZBC',3,'John Smith'],
[2,“FBC”,5,“Mike Tyson”],
[3'ABC',7'唐老鸭'],
[
- sort by the first column
- if equal, sort by the second
- if equal, sort by the third
- etc... nesting and nesting if-else
// useful for chaining test
const decide = (test, other) => test === 0 ? other : test
const multisort = (s1, s2) => {
const bcs = -1 * byCountrySize(s1, s2) // -1 = desc
const ba = 1 *byAge(s1, s2)
const bgt = 0 * byGameType(s1, s2) // 0 = doesn't matter
const bs = 1 * byScore(s1, s2)
const bl = -1 * byLevel(s1, s2) // -1 = desc
// ... other weights and criterias
// array order matters !
return [bcs, ba, bgt, bs, bl].reduce((acc, val) => decide(val, acc), 0)
}
// invoke [].sort with custom sort...
scores.sort(multisort)
t.sort( (a,b)=> a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]) );