Сортировка массива с определенным условием - PullRequest
0 голосов
/ 27 апреля 2019

Я пытаюсь отсортировать массив 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 голосов
/ 28 апреля 2019

Похоже, что объекты должны быть "отсортированы" перед сравнением:

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 ') );
0 голосов
/ 28 апреля 2019

Я не думаю, что 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"]
]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...