特定条件的排序数组

时间:2019-04-27 11:51:31

标签: javascript arrays sorting

我正在尝试对具有特定条件的JavaScript数组进行排序。我尝试使用array.sort(),但是它并没有达到我想要的方式。

我有一个像这样的数组:

leftTable = [
    {tableL:"A", tableR:"E"},
    {tableL:"A", tableR:"E"},
    {tableL:"C", tableR:"D"},
    {tableL:"H", tableR:"A"},
    {tableL:"F", tableR:"G"},
    {tableL:"E", tableR:"A"},
];

我想这样排序:

leftTable = [
    {tableL:"A", tableR:"E"},
    {tableL:"A", tableR:"E"},
    {tableL:"E", tableR:"A"},
    {tableL:"H", tableR:"A"},
    {tableL:"C", tableR:"D"},
    {tableL:"F", tableR:"G"},
];

但是我得到的是这个

leftTable = [
    {tableL: "A", tableR: "E"},
    {tableL: "A", tableR: "E"},
    {tableL: "C", tableR: "D"},
    {tableL: "E", tableR: "A"},
    {tableL: "F", tableR: "G"},
    {tableL: "H", tableR: "A"}
]

我已经尝试了几次,但没有成功。到目前为止,这是我尝试过的一件事:

leftTable.sort(function(a, b) {
    console.log(a.tableL,a.tableR,b.tableL,b.tableR);
    if (a.tableL < b.tableL) {
        return -1;
    } else if (a.tableL > b.tableL) {
       return 1;
    } else if (a.tableL == b.tableL) {
        if(a.tableR == b.tableR) return -1; else return 1;
    } else if (a.tableL == b.tableR) {
        if(a.tableR == b.tableL) return -1; else return 1;
    } else {
        return 0;
    }
});

我的排序逻辑是:

如果值是{"A","E"},并且下一个对象具有相同的值,但是与{"E","A"}一样,我希望它们被排序在一起。如果其中一个值包含至少一个之前的值,例如{"H","A"}{"A","K"},则同样。

但是我得到的是数组只是像往常一样以升序排序。

我可以知道是否有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

我认为Array.prototype.sort不足以完成您想要的事情,下面的事情可以做到。

const getSorted = _entries => {
  let sortedEntries = [];
  let entries = [..._entries]; // make a copy so that will don't mutate original (optional)
  
  while (entries.length > 0) {
    let currEntry = entries.shift();
    let matches = entries.reduce((matches, entry) => {
      if (
        entry.includes(currEntry[0]) &&
        entry.includes(currEntry[1])
      ) {
        entries.splice(entries.indexOf(entry), 1); // remove the matched from original
        matches.push({ entry, pref: 0 }); // if it includes both that is more preferred
        return matches;
      }

      if (
        entry.includes(currEntry[0]) ||
        entry.includes(currEntry[1])
      ) {
        entries.splice(entries.indexOf(entry), 1); // remove the matched from original
        matches.push({ entry, pref: 1 }); // if it includes only one that is less preferred
        return matches;
      }
      
      return matches;
    }, [])
    .sort((a,b) => a.pref - b.pref) // sort by preference
    .map(({ entry }) => entry); // we no longer need pref, only need entry 
    
    sortedEntries.push(currEntry);
    sortedEntries.push(...matches);
  }
  
  return sortedEntries;
}

console.log(getSorted([
  ["A", "E"],
  ["A", "E"],
  ["C", "D"],
  ["H", "A"],
  ["F", "G"],
  ["E", "A"]
]))

答案 1 :(得分:0)

在比较之前,应先对类似对象的声音进行“排序”:

var leftTable = [ { tableL: "A", tableR: "E" },
                  { tableL: "A", tableR: "E" },
                  { tableL: "C", tableR: "D" },
                  { tableL: "H", tableR: "A" },
                  { tableL: "F", tableR: "G" },
                  { tableL: "E", tableR: "A" } ];

leftTable.sort(function(a, b) { return [a.tableL, a.tableR].sort().join()
                        .localeCompare([b.tableL, b.tableR].sort().join()); });

console.log( JSON.stringify( leftTable ).replace(/},/g, '},\n ') );


对于可变长度的字符串,可能需要自定义数组比较功能:

var leftTable = [ { tableL: "A", tableR: "E" },
                  { tableL: "A", tableR: "E" },
                  { tableL: "C", tableR: "D" },
                  { tableL: "H", tableR: "A" },
                  { tableL: "F", tableR: "G" },
                  { tableL: "E", tableR: "A" } ];

leftTable.sort(function(a, b) { 
  a = [a.tableL, a.tableR].sort();
  b = [b.tableL, b.tableR].sort();
  return a[0] - b[0] || a[1] - b[1]; 
});

console.log( JSON.stringify( leftTable ).replace(/},/g, '},\n ') );