首页 > 解决方案 > 具有特定条件的排序数组

问题描述

我正在尝试对具有特定条件的 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"}

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

我可以知道是否有更好的方法来做到这一点?

标签: javascriptarrayssorting

解决方案


我认为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"]
]))


推荐阅读