按特定数组的顺序对其他数组进行排序?

时间:2016-12-06 08:39:50

标签: javascript arrays sorting rowsorter

我有一堆这种形式的数组:

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属性,可能甚至可以这样做吗?

5 个答案:

答案 0 :(得分:2)

您可以使用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; }




答案 1 :(得分:1)

当你删除idx属性时,你可以使用一个数组:



// Function copied from here: http://stackoverflow.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)




答案 2 :(得分:1)

你可以这样做。

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

这是一个非常简单的代码,只是为了证明这个想法。 对于非常大的数组,它可能会很慢。

答案 3 :(得分:1)

您可以执行以下操作,

  • 对数组 1 的第一行进行排序,并将其idx es存储在临时数组 2
  • 根据第一个temp 3
  • 为剩余数组分配idx属性
  • 根据temp属性 4 (基于第一个数组)对剩余数组进行排序
  • 删除temp属性 5

<强> E.g。

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

答案 4 :(得分:0)

使用hash table根据第一行创建排序条件 - 请参阅下面的演示:

&#13;
&#13;
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);
&#13;
.as-console-wrapper{top:0;max-height:100%!important;}
&#13;
&#13;
&#13;