Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在多个列上对数组进行排序?_Javascript_Algorithm_Sorting - Fatal编程技术网

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]) );