Sort object array with relation to each other

Asked

Viewed 115 times

0

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

Something more or less like this:

... demais campos
id
prev_id
next_id

I need to draw these objects that come from the database somehow. I tried using the method .sort() Javascript, but no 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 assembled a small example above using a array and, in a comment, the array that needs to be achieved through ordination.


It is important to note that as the data comes from a database, I cannot 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 on the list, it gets its own ID in the field prev. Something similar happens with the latter, which receives its own ID in the field next.

  • Hello Luiz! Could you give us feedback? None of the answers answered you? We can debate and come up with a solution that meets your purpose if you want. Abs!

2 answers

0

Hello apparently is one of logic, I did it the way below and it worked.

Following 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;
     }
});
  • I do not believe that this is valid, since the ID’s do not directly influence this (I mean influence with regard to one being greater than the other). I will edit the answer to make it clear.

  • All right Luiz, I’m on hold.

  • I edited there! If you got confused can warn. Thanks!

  • I still don’t understand why id 5 is the first

  • The data (objects) come from a relational database. The id is an auto-increment (primary) field.

  • I’ll remove the answer tomorrow I think of something

Show 1 more comment

0

There would be no way to compare words, whether one is "greater or lesser" in this way. For example, in alphabetical order the word "Second" would be larger than "Fourth". A form would be to use an auxiliary object where each word would have an associated numerical value, i.e., "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);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.