skip to Main Content

I need to sort array based on another.

Arr1

const arr1 =[ 
{id: 74, name: 'Mat', type: 'bus'},
{id: 2, name: 'Johan',  type: 'plane'} 
{id: 25,  name: 'Kevin', type: 'car'},
{id: 10, name: 'Mary',  type: 'plane'},
{id: 34, name: 'Katrin',  type: 'car'}  
]  

Arr2

const arr2 =[ 
{id: 25},
{id: 34},
{id: 10}, 
]  
or without id ... it does not matter 
const arr2 =["25","34", "10"]  

What I want to get back is sorted array with the rest ids that is not in the second array

const arr1 =[ 
{id: 25,  name: 'Kevin', type: 'car'},
{id: 34, name: 'Katrin',  type: 'car'} 
{id: 10, name: 'Mary',  type: 'plane'},
{id: 74, name: 'Mat', type: 'bus'},
{id: 2, name: 'Johan',  type: 'plane'}  
]

I found several solutions, but no one of them deal with the rest of objects that are not in array2 (id:74 and id:2). Any suggestions?

2

Answers


  1. Find indices of IDs and sort accordingly. You could also cache the indices in a Map, works a bit faster:

    enter image description here

    <script benchmark data-count="1000000">
    
      // @benchmark easy solution
    {
      const arr1 =[ 
        {id: 74, name: 'Mat', type: 'bus'},
        {id: 2, name: 'Johan',  type: 'plane'},
        {id: 25,  name: 'Kevin', type: 'car'},
        {id: 10, name: 'Mary',  type: 'plane'},
        {id: 34, name: 'Katrin',  type: 'car'}  
        ];
        const arr2 =[25,34, 10];
    
        arr1.sort((a, b) => {
          const [idxA, idxB] = [a, b].map(what => arr2.findIndex(item => item === what.id));
          if(idxA === idxB){ // -1
            return 0;
          }
          if(idxA === -1){
            return 1;
          }
          if(idxB === -1){
            return -1;
          }
          return idxA - idxB;
    
        });
    }
    
      // @benchmark optimized solution
    {
        const arr1 =[ 
        {id: 74, name: 'Mat', type: 'bus'},
        {id: 2, name: 'Johan',  type: 'plane'},
        {id: 25,  name: 'Kevin', type: 'car'},
        {id: 10, name: 'Mary',  type: 'plane'},
        {id: 34, name: 'Katrin',  type: 'car'}  
        ];
    
        const arr2 =[25,34, 10];
    
        // cache indices
        const indices = arr2.reduce((map, item, idx) => map.set(item, idx), new Map);
    
        arr1.sort((a, b) => {
          const [idxA, idxB] = [indices.get(a.id) ?? -1, indices.get(b.id) ?? -1];
    
          if(idxA === idxB){ // -1
            return 0;
          }
          if(idxA === -1){
            return 1;
          }
          if(idxB === -1){
            return -1;
          }
          return idxA - idxB;
    
        });
    }
    </script>
    <script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>
    Login or Signup to reply.
  2. This should do it.

    const 
         arr1 = [ {id: 74, name: 'Mat', type: 'bus'}, {id: 2, name: 'Johan', type: 'plane'}, {id: 25, name: 'Kevin', type: 'car'}, {id: 10, name: 'Mary', type: 'plane'}, {id: 34, name: 'Katrin', type: 'car'} ],
         
         arr2 = [25, 34, 10],
         
         getIndex = (n, a) => a.includes(n) ? a.indexOf(n) : a.length;
    
         sorted = arr1.sort(
            (a,b) => 
            getIndex(a.id, arr2) - getIndex(b.id, arr2)
         );
    
    console.log( sorted );
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search