Sort array of objects relative to each other

0

I came across a problem: I have data coming from a database that are related to each other so that each field has two others - one referring to the previous field (in the table) and the other to the next field.

Something like this:

... demais campos
id
prev_id
next_id

I need to sort out those objects that come from the database in some way. I tried using the .sort() method of JavaScript, but I did not get any success:

const positions = [
  { name: 'Segundo', id: 2, prev: 1, next: 3 },
  { name: 'Quarto', id: 4, prev: 3, next: 4 },
  { name: 'Primeiro', id: 1, prev: 1, next: 2 },
  { name: 'Terceiro', id: 3, prev: 2, next: 3 }
]

/**
 * Deve ficar assim:
 * 
 * { name: 'Primeiro', id: 1, prev: 1, next: 2 },
 * { name: 'Segundo', id: 2, prev: 1, next: 3 },
 * { name: 'Terceiro', id: 3, prev: 2, next: 3 },
 * { name: 'Quarto', id: 4, prev: 3, next: 4 }
 */

const newArray = positions.sort((a, b) => {
  if (a.prev === b.id) return 1
  if (a.next === b.id) return -1
  return 0
})

console.log(newArray)

I've put a small example above using an initial array and in a comment, the array that needs to be reached through sorting.

It's important to note that because the data comes from a database, I can not necessarily assume that the IDs will be in order.

Another example to illustrate this situation:

const positions = [
  { name: 'Quarto', id: 3, prev: 1, next: 3 },
  { name: 'Primeiro', id: 5, prev: 5, next: 7 },
  { name: 'Segundo', id: 7, prev: 5, next: 1 },
  { name: 'Terceiro', id: 1, prev: 7, next: 3 }
]

// Deve ficar:
const sorted = [
  { name: 'Primeiro', id: 5, prev: 5, next: 7 },
  { name: 'Segundo', id: 7, prev: 5, next: 1 },
  { name: 'Terceiro', id: 1, prev: 7, next: 3 },
  { name: 'Quarto', id: 3, prev: 1, next: 3 }
]

Another addendum is that if the item is first in the list, it gets its own ID in the prev field. Something similar happens with the latter, which gets its own ID in the next field.

    
asked by anonymous 28.08.2018 / 02:34

2 answers

0

Hello apparently it's a logic one, I did it the way below and it worked.

  

Here's an example:

positions.sort(function (a,b) {
     if(a.prev <= b.prev && a.next <= b.next) {
             return -1;
     } else if(a.prev == b.prev && a.next == b.next) {
             return 0;
     } else {
             return 1;
     }
});
    
28.08.2018 / 02:45
0

I could not compare words, if one is "bigger or smaller" in this way. For example, in alphabetical order the word "Second" would be greater than "Room". One way would be to use an auxiliary object where each word would have an associated numeric value, ie "First = 1", "Second = 2", and so on.

So you can make the comparisons by the value assigned to the words:

const pos = {
   'Primeiro': 1,
   'Segundo': 2,
   'Terceiro': 3,
   'Quarto': 4
}

const positions = [
  { name: 'Segundo', id: 2, prev: 1, next: 3 },
  { name: 'Quarto', id: 4, prev: 3, next: 4 },
  { name: 'Primeiro', id: 1, prev: 1, next: 2 },
  { name: 'Terceiro', id: 3, prev: 2, next: 3 }
]

const sorted = positions.sort(function (a,b) {
   if(pos[a.name] > pos[b.name]) return 1;
});
console.log(sorted);
    
28.08.2018 / 04:48