3

I have one array:

const CORRECT_ORDER = ['Animal','Plant','Sand','Grass'];

Then I have another array of Objects:

const UNSORTED = [{Type: 'Grass', Value: 'Wet'}, {Type: 'Sand', Value: 'Dry'}, {Type: 'Animal', Value: 'Dog'}];

I want to sort the UNSORTED array so that the Animal type comes first, followed by Plant then Sand and Grass.

If the CORRECT_ORDER array changes order I should be able to resort the UNSORTED array to match the new order.

It is safe to assume that no Types (Grass, Sand, Plant, Animal) will repeat and that type will only show up once in the unsorted array, if at all.


I have tried something like the following: PSUEDO CODE:

const SORTED = [];
UNSORTED.ForEach(value){
 const positionIndex = CORRECT_ORDER.indexOf(value.Type);

 if(positionIndex > SORTED.length){
   //Push at end
   SORTED.push(value);
 } else {
   //Push at index
   SORTED.splice(positionIndex, 0, value);
 }
}

return SORTED;

Unfortunately this isn't foolproof and it often sorts things incorrectly, especially on datasets that are a big larger.

Jammy
  • 57
  • 1
  • 4
  • 2
    this helps? https://stackoverflow.com/questions/14872554/sorting-on-a-custom-order – cmgchess Mar 15 '22 at 20:23
  • well a simple solution is to do a search, find and insert to a new array. suppose we want to Animal come first, then we search the array for the animal type, find the Object and insert it to new array, and do the same thing for other objects. until all other objects have been inserted to the new array in the other words they been sorted – Me Bottle O Scrumpy Mar 15 '22 at 20:26
  • this is wrongly marked as a duplicate. The suggested solution depicts a completely different use case – jmrodriguez Jul 06 '23 at 17:02

4 Answers4

1

You can loop the correct_order array and filter the unsorted array by using the js filter function. If filter match push to an new array.

const UNSORTED = [{Type: 'Grass', Value: 'Wet'}, {Type: 'Sand', Value: 'Dry'}, {Type: 'Animal', Value: 'Dog'}];

const CORRECT_ORDER = ['Animal','Plant','Sand','Grass'];

let sorted = []
CORRECT_ORDER.forEach(k => {
  let n = UNSORTED.filter(obj => {
    return obj.Type === k
  })
  if (n.length > 0) {
    sorted.push(n);  
  }
  
})

console.log(sorted);
Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
  • 1
    Hi, not sure if it matters but you got the CORRECT_ORDER and UNSORTED array values mixed up. –  Jammy Mar 15 '22 at 20:34
  • @Jammy Thank you and you are right i mixed up. Now is fixed ;-) Merci! – Maik Lowrey Mar 15 '22 at 20:37
  • i only changed line `sorted.push(n)` to `sorted.push(...n)` because the original code added an array of 1 element in each position of the "sorted" array. BTW, this question is marked as a duplicate of another one that is a completely different case. This one sorts based on a string property to be found inside the unsorted array. The answer this one is marked as a "duplicate of" sorts based on an array that specifies the position of the elements you want to get returned. – jmrodriguez Jul 06 '23 at 17:01
1

i made a simple example sorting objects by their Type's index in the CORRECT_ORDER table:

const order = ['Animal','Plant','Sand','Grass'];
const unsorted = [{Type: 'Grass', Value: 'Wet'}, {Type: 'Sand', Value: 'Dry'}, {Type: 'Animal', Value: 'Dog'}];

const sorted = unsorted.sort((a,b) => {
    const indexA = order.findIndex(type => a.Type === type);
    const indexB = order.findIndex(type => b.Type === type);
  return indexA - indexB; // to get positive, 0, negative number for the sort callback.
});

console.log(sorted);

You can check its implementation in JSFiddle

sohaieb azaiez
  • 768
  • 9
  • 20
0

Try this

function sort() {
 const map = {}
 CORRECT_ORDER.map((type, i) => (map[type] = i))
 const sortedArr = UNSORTED.sort((a, b) => map[a.Type] - map[b.Type])
 return sortedArr
}
Aaron Vasilev
  • 438
  • 2
  • 6
0

const CORRECT_ORDER = ['Animal','Plant','Sand','Grass'];

const UNSORTED = [{Type: 'Grass', Value: 'Wet'}, {Type: 'Sand', Value: 'Dry'}, {Type: 'Animal', Value: 'Dog'}];


function sort_objects(order, unsortedArray){

    let newArray = Array();

    for(i = 0; i < order.length; i++){

        for(j = 0; j < unsortedArray.length; j++){

            if(unsortedArray[j].Type == order[i]){
                newArray.push(unsortedArray[j]);
                break;
            }
        }

    }

    return newArray

}


console.log(sort_objects(CORRECT_ORDER, UNSORTED))

this might work but it can be made more efficient.

Me Bottle O Scrumpy
  • 266
  • 1
  • 3
  • 12