Javascript:基于第一个数组排序结果对多维数组进行排序

时间:2023-01-21 21:31:00

I have an array setup similar to this:

我有一个类似于这个的数组设置:

var ary1 = new Array("d", "a", "b", "c");
var ary2 = new Array("ee", "rr", "yy", "mm");

var mdAry = new Array(ary1, ary2);

ary1 and ary2 indexes are info related to each other in the grand scheme of things.

ary1和ary2索引是在宏观方案中相互关联的信息。

d ee
a rr
b yy
c mm

I can sort() ary1 and get:

我可以排序()ary1并得到:

a
b
c
d

but if I sorted ary2 independently I would get:

但如果我独立排序ary2,我会得到:

ee
mm
rr
yy

which visually breaks ary1 and ary2 connections when listed out. Can I retrieve ary1's sorted solution and apply that to ary2? I want to get this:

在列出时可视地打破ary1和ary2连接。我可以检索ary1的已排序解决方案并将其应用于ary2吗?我想得到这个:

a rr
b yy
c mm
d ee

If not, could mdAry be sorted so that it applies mdAry[0] sorted solution to the remaining indicies?

如果没有,可以对mdAry进行排序,以便将mdAry [0]排序解决方案应用于其余的指标吗?

5 个解决方案

#1


0  

You could "merge" them into a single object with two properties, sort by the first one, and then separate back in the end (see demo here):

您可以将它们“合并”到具有两个属性的单个对象中,按第一个排序,然后在最后分开(请参见此处的演示):

function sortBoth(ary1, ary2) {
    var merged = [];
    for (var i=0; i < ary1.length; i++) merged.push({'ary1': ary1[i], 'ary2': ary2[i]});
    merged.sort(function(o1, o2) { return ((o1.ary1 < o2.ary1) ? -1 : ((o1.ary1 == o2.ary1) ? 0 : 1)); });
    for (var i=0; i < merged.length; i++) { ary1[i] = merged[i].ary1; ary2[i] = merged[i].ary2; }
}

var ary1 = new Array("d", "a", "b", "c");
var ary2 = new Array("ee", "rr", "mm", "yy");

console.log(ary1);
console.log(ary2);

sortBoth(ary1, ary2);

console.log(ary1);
console.log(ary2);

Output:

[ "d",  "a",  "b",  "c"]
["ee", "rr", "mm", "yy"]
[ "a",  "b",  "c",  "d"]
["rr", "mm", "yy", "ee"] 

#2


3  

If your array items are related, then store them together:

如果您的数组项是相关的,则将它们存储在一起:

var arr = [
  {x: 'd', y: 'ee'}, 
  {x: 'a', y: 'rr'}, 
  {x: 'b', y: 'yy'},
  {x: 'c', y: 'mm'}
];

arr.sort(function(a, b) {
  if (a.x != b.x) {
      return a.x < b.x ? -1 : 1;
  }
  return 0;
});

#3


1  

One way to do this is to transform the data structure to something that can be sorted more easily, and then transform it back after

实现此目的的一种方法是将数据结构转换为可以更容易排序的内容,然后将其转换回来

var ary1  = ["d", "a", "b", "c"],
    ary2  = ["ee", "rr", "mm", "yy"]
    mdAry = [ary1, ary2];

// convert to form [[d, ee], [a, rr], ..]
var tmp = mdAry[0].map(function (e, i) {
    return [e, mdAry[1][i]];
});
// sort this
tmp.sort(function (a, b) {return a[0] > b[0];});
// revert to [[a, b, ..], [rr, mm, ..]]
tmp.forEach(function (e, i) {
    mdAry[0][i] = e[0];
    mdAry[1][i] = e[1];
});
// output
mdAry;
// [["a", "b", "c", "d"], ["rr", "mm", "yy", "ee"]]

#4


1  

Just to add yet another method in there, you could get a sort "result" from the first array and apply that to any other related list:

只是在那里添加另一个方法,你可以从第一个数组得到一个排序“结果”并将其应用于任何其他相关列表:

function getSorter(model) {
    var clone = model.slice(0).sort();
    var sortResult = model.map(function(item) { return clone.indexOf(item); });

    return function(anyOtherArray) {
        result = [];
        sortResult.forEach(function(idx, i) {
            result[idx] = anyOtherArray[i];
        });
        return result;
    }
}

Then,

var arr = ["d", "a", "b", "c"];
var arr2 = ["ee", "rr", "yy", "mm"];

var preparedSorter = getSorter(arr);
preparedSorter(arr2); 
//=> ["rr", "yy", "mm", "ee"];

Or,

multidimensional = [arr, arr2];
multidimensional.map(getSorter(arr)); 
// => [["a", "b", "c", "d"], ["rr", "yy", "mm", "ee"]]

#5


0  

In your example the result should be (if I understand correctly)

在你的例子中,结果应该是(如果我理解正确)

a rr
b mm
c yy
d ee

So this one should to the job:

所以这个应该到这个工作:

Array.prototype.sortRelated = function(related) {
    var clone = this.slice(0), 
        sortedRelated = [];
    clone.sort();

    for(var i = 0; i < this.length; i ++) {
        sortedRelated[clone.indexOf(this[i])] = related[i];
    }

    return sortedRelated;
}

var ary1 = new Array("d", "a", "b", "c");
var ary2 = new Array("ee", "rr", "mm", "yy");

var sorted = ary1.sortRelated(ary2);

Working demo here: http://jsfiddle.net/cwgN8/

这里的工作演示:http://jsfiddle.net/cwgN8/

#1


0  

You could "merge" them into a single object with two properties, sort by the first one, and then separate back in the end (see demo here):

您可以将它们“合并”到具有两个属性的单个对象中,按第一个排序,然后在最后分开(请参见此处的演示):

function sortBoth(ary1, ary2) {
    var merged = [];
    for (var i=0; i < ary1.length; i++) merged.push({'ary1': ary1[i], 'ary2': ary2[i]});
    merged.sort(function(o1, o2) { return ((o1.ary1 < o2.ary1) ? -1 : ((o1.ary1 == o2.ary1) ? 0 : 1)); });
    for (var i=0; i < merged.length; i++) { ary1[i] = merged[i].ary1; ary2[i] = merged[i].ary2; }
}

var ary1 = new Array("d", "a", "b", "c");
var ary2 = new Array("ee", "rr", "mm", "yy");

console.log(ary1);
console.log(ary2);

sortBoth(ary1, ary2);

console.log(ary1);
console.log(ary2);

Output:

[ "d",  "a",  "b",  "c"]
["ee", "rr", "mm", "yy"]
[ "a",  "b",  "c",  "d"]
["rr", "mm", "yy", "ee"] 

#2


3  

If your array items are related, then store them together:

如果您的数组项是相关的,则将它们存储在一起:

var arr = [
  {x: 'd', y: 'ee'}, 
  {x: 'a', y: 'rr'}, 
  {x: 'b', y: 'yy'},
  {x: 'c', y: 'mm'}
];

arr.sort(function(a, b) {
  if (a.x != b.x) {
      return a.x < b.x ? -1 : 1;
  }
  return 0;
});

#3


1  

One way to do this is to transform the data structure to something that can be sorted more easily, and then transform it back after

实现此目的的一种方法是将数据结构转换为可以更容易排序的内容,然后将其转换回来

var ary1  = ["d", "a", "b", "c"],
    ary2  = ["ee", "rr", "mm", "yy"]
    mdAry = [ary1, ary2];

// convert to form [[d, ee], [a, rr], ..]
var tmp = mdAry[0].map(function (e, i) {
    return [e, mdAry[1][i]];
});
// sort this
tmp.sort(function (a, b) {return a[0] > b[0];});
// revert to [[a, b, ..], [rr, mm, ..]]
tmp.forEach(function (e, i) {
    mdAry[0][i] = e[0];
    mdAry[1][i] = e[1];
});
// output
mdAry;
// [["a", "b", "c", "d"], ["rr", "mm", "yy", "ee"]]

#4


1  

Just to add yet another method in there, you could get a sort "result" from the first array and apply that to any other related list:

只是在那里添加另一个方法,你可以从第一个数组得到一个排序“结果”并将其应用于任何其他相关列表:

function getSorter(model) {
    var clone = model.slice(0).sort();
    var sortResult = model.map(function(item) { return clone.indexOf(item); });

    return function(anyOtherArray) {
        result = [];
        sortResult.forEach(function(idx, i) {
            result[idx] = anyOtherArray[i];
        });
        return result;
    }
}

Then,

var arr = ["d", "a", "b", "c"];
var arr2 = ["ee", "rr", "yy", "mm"];

var preparedSorter = getSorter(arr);
preparedSorter(arr2); 
//=> ["rr", "yy", "mm", "ee"];

Or,

multidimensional = [arr, arr2];
multidimensional.map(getSorter(arr)); 
// => [["a", "b", "c", "d"], ["rr", "yy", "mm", "ee"]]

#5


0  

In your example the result should be (if I understand correctly)

在你的例子中,结果应该是(如果我理解正确)

a rr
b mm
c yy
d ee

So this one should to the job:

所以这个应该到这个工作:

Array.prototype.sortRelated = function(related) {
    var clone = this.slice(0), 
        sortedRelated = [];
    clone.sort();

    for(var i = 0; i < this.length; i ++) {
        sortedRelated[clone.indexOf(this[i])] = related[i];
    }

    return sortedRelated;
}

var ary1 = new Array("d", "a", "b", "c");
var ary2 = new Array("ee", "rr", "mm", "yy");

var sorted = ary1.sortRelated(ary2);

Working demo here: http://jsfiddle.net/cwgN8/

这里的工作演示:http://jsfiddle.net/cwgN8/