-2

I have a array that I'm moving a selected element to the top(like it's pinned), now I want to move it back where it was before in the list which I compare the IDs, so want to show the pinned elements (that does have a key pinned:true) to the top of array, and the ones that does not a key pinned: true will be sorted by id.

All goes as desired, except when i want to show them as sorted by id which smaller ids will go to the top and greater will go after (1,2,3,4...)

Here is a sandbox where you can get a good idea of what's going on

https://codesandbox.io/s/serene-brattain-cro18?file=/src/App.tsx

const data = [
  { name: "Josef", id: 1 },
  { name: "Ali", id: 2 },
  { name: "Sheyda", id: 3 },
  { name: "Parviz", id: 4 },
  { name: "Victor", id: 5 },
  { name: "Mike", id: 6 },
  { name: "Ross", id: 7 },
  { name: "Chandler", id: 8 },
  { name: "Monica", id: 9 }
];
   data.sort(function (x,y) {
      return x.pinned === y.pinned ? 0 : x.pinned ? -1 : 1;
  });
   console.log(data)

So the point is I want the items with key pinned:true to be at the first(which item get true when i click on it and when I click back it gets false, and by default it's undefined) and the other with key pinned set to false and undefined will go under them and will be sorted by ids

Currently i am able to sort them as pinned:true to the top and the other under them but I cannot sort the ones with false by IDs

Yaya
  • 4,402
  • 4
  • 19
  • 43
  • You should post your code in a code block here. Also if you could produce a Minimal Reproducible Example, i.e. just example input and a few lines of JS (your sorter), that helps a lot for people that want to answer. – Kelvin Schoofs Aug 04 '21 at 22:45
  • Does this answer your question? [How to sort an array of objects by multiple fields?](https://stackoverflow.com/questions/6913512/how-to-sort-an-array-of-objects-by-multiple-fields) – pilchard Aug 04 '21 at 23:07

1 Answers1

1

Your problem is that you're sorting just by whether one element is pinned while the other is not.

In your case, you basically want something like this:

// [value: number, pinned: boolean][]
const data = [];
for (let i = 0; i < 20; i++) {
    data.push([Math.random() * 100, Math.random() < 0.5]);
}

data.sort((a, b) => {
    const [aValue, aPinned] = a;
    const [bValue, bPinned] = b;
    if (aPinned !== bPinned) return  aPinned ? -1 : 1;
    return aValue - bValue;
});

console.log(data.map(([val, pinned]) => `${pinned ? '[!] ' : ''} ${val}`).join('\n'));
Kelvin Schoofs
  • 8,323
  • 1
  • 12
  • 31