按特定数组的顺序排序其他数组?
问题描述:
我有这种形式一堆阵列:按特定数组的顺序排序其他数组?
var myRows = [
[{idx: 0, val: 90}, {idx: 1, val: 75}, {idx: 2, val: 35}],
[{idx: 0, val: 50}, {idx: 1, val: 17}, {idx: 2, val: 95}],
[{idx: 0, val: 10}, {idx: 1, val: 24}, {idx: 2, val: 80}]
// ...
];
可以说,我想通过val
第一行升序排序,所以就变成:
[{idx: 2, val: 35}, {idx: 1, val: 75}, {idx: 0, val: 90}]
有没有一种简单的方法对剩余的数组进行排序,以便它们的顺序与排序的第一行的idx
-顺序匹配?
myArrays = [
[{idx: 2, val: 35}, {idx: 1, val: 75}, {idx: 0, val: 90}]
, [{idx: 2, val: 95}, {idx: 1, val: 17}, {idx: 0, val: 50}]
, [{idx: 2, val: 80}, {idx: 1, val: 24}, {idx: 0, val: 10}]
// ...
];
也许这甚至可能没有idx
属性?
答
您可以使用sorting with map并为所有项目应用映射。
该建议保存索引,对数组进行排序并将顺序应用于所有其他数组。
// the array to be sorted
var list = [[{ idx: 0, val: 90 }, { idx: 1, val: 75 }, { idx: 2, val: 35 }], [{ idx: 0, val: 50 }, { idx: 1, val: 17 }, { idx: 2, val: 95 }], [{ idx: 0, val: 10 }, { idx: 1, val: 24 }, { idx: 2, val: 80 }]];
// temporary array holds objects with position and sort-value
var mapped = list[0].map(function (el, i) {
return { index: i, value: el.val };
})
// sorting the mapped array containing the reduced values
mapped.sort(function (a, b) {
return a.value - b.value;
});
// rearrange all items in list
list.forEach(function (a, i, aa) {
aa[i] = mapped.map(function (el) {
return a[el.index];
});
});
console.log(list);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答
当你放下IDX属性,你可以使用数组:
// Function copied from here: http://*.com/a/36164530/5710637
var transpose = m => m[0].map((x,i) => m.map(x => x[i]))
var sortByRow = 0
var myRows = [
[90, 75, 35],
[50, 17, 95],
[10, 24, 80]
]
var myCols = transpose(myRows)
myCols.sort((x, y) => x[sortByRow] - y[sortByRow])
myRows = transpose(myCols)
console.log(myRows)
答
你可以做这样的事情。
var order = myRows[0].map(function(e) { return e.idx })
myRows.forEach(function(row) {
row.sort(function(a,b) {
return order.indexOf(a.idx) - order.indexOf(b.idx);
});
});
这是非常简单的代码,只是为了展示这个想法。 对于非常大的数组,它可能会很慢。
答
使用hash table
创建基于第一行上的排序标准 - 看演示如下:
var myRows=[[{idx:0,val:90},{idx:1,val:75},{idx:2,val:35}],[{idx:0,val:50},{idx:1,val:17},{idx:2,val:95}],[{idx:0,val:10},{idx:1,val:24},{idx:2,val:80}]];
// sort the first row (as desired)
myRows[0].sort((a,b) => a.val - b.val);
myRows.forEach(function(c,i){
if(i === 0){
// create order criteria based on first row
c.forEach(function(e, k){
this[e.idx] = k;
});
} else {
c.sort(function(a,b) {
return this[a.idx] - this[b.idx];
});
}
}, Object.create(null));
console.log(myRows);
.as-console-wrapper{top:0;max-height:100%!important;}
答
你可以做以下这呢,
- 排序阵列的第一行,和它们的
idx
ES存储在临时阵列 - 根据第一
idx
- 排序与
temp
属性分配剩余的阵列其余阵列基于他们的temp
属性(它基于第一个阵列) - 删除
temp
属性
例如
var filteredRows = [];
var myRows = [
[{idx: 0, val: 90}, {idx: 1, val: 75}, {idx: 2, val: 35}],
[{idx: 0, val: 50}, {idx: 1, val: 17}, {idx: 2, val: 95}],
[{idx: 0, val: 10}, {idx: 1, val: 24}, {idx: 2, val: 80}]
];
/* 1. Sort the first row */
myRows[0].sort(function(a, b) {
return a.val - b.val;
});
filteredRows.push(myRows[0]);
/* 2. Get indexes */
var idxs = [];
for (var obj of myRows[0]) {
idxs.push(obj.idx);
}
/* Handle the remaining array */
myRows.slice(1).map(function (val) {
/* 3. Assign temp value */
val.map(function (obj, i) {
obj.temp = idxs[i];
});
/* 4. Sort them */
val.sort(function (a, b) {
return a.temp - b.temp;
});
/* 5. Remove temp value */
val.map(function (obj, i) {
delete obj.temp;
});
});
console.log(JSON.stringify(myRows));