Skip to content Skip to sidebar Skip to footer

Custom Sort Between Two Values

if the array is something like: const arr = [ { level: 'mid' } , { level: 'senior' } , { level: 'junior' } , { level: 'senior' } , { level: 'mid' } , { level: 'j

Solution 1:

Try sorting like this

functionsortArray() {
  var arr = [{ 'level': 'mid' }, { 'level': 'senior' }, { 'level': 'junior' }, { 'level': 'senior' }, { 'level': 'mid' }, { 'level': 'junior' }, { 'level': 'entry' }];
    
  arr = arr.sort((a, b) => (a.level > b.level) ? 1 : -1)
    
  console.log(arr);
}

Solution 2:

You will have to use a custom sort function where:

  1. All of your non junior/senior levels are moved upfront. (This does a partition in your array )
  2. You specifically handle the case of junior and senior.

let arr = [{ 'level' : 'mid' },{'level' : 'senior' }, { 'level' : 'junior' }, { 'level' : 'senior' }, { 'level' : 'mid' }, { 'level' : 'junior' }, { 'level' : 'entry' }];

arr.sort((a, b) => {  if(['mid','entry'].indexOf(b.level) > -1) return1;

elseif(b.level === 'junior' && a.level === 'senior') return1;

return -1;
});
 
console.log(arr);

Solution 3:

arr.level is a string. Use localeCompare to sort on strings:

constlevelSortAscending = (a, b) => a.level.localeCompare(b.level);
constlevelSortDescending = (a, b) => b.level.localeCompare(a.level);
const arr = [
  { 'level' : 'mid' },
  { 'level' : 'senior' }, 
  { 'level' : 'junior' }, 
  { 'level' : 'senior' }, 
  { 'level' : 'mid' },
  { 'level' : 'junior' },
  { 'level' : 'entry' } ]
  .sort( levelSortAscending );
  
document.querySelector('pre').textContent = `---ascending---\n${
  JSON.stringify(arr, null, 2)}`;
document.querySelector('pre').textContent += `\n\n---descending---\n${
  JSON.stringify(arr.sort( levelSortDescending ), null, 2)}`;
<pre></pre>

But you don't want to sort the array. Cf your comment you want to reshuffle it. So:

const arr = [
  { 'level' : 'mid' }, { 'level' : 'senior' }, { 'level' : 'junior' }, 
  { 'level' : 'senior' }, { 'level' : 'mid' }, { 'level' : 'junior' },
  { 'level' : 'entry' } ];
  
const intermediate = arr.reduce( (acc, val) => 
  val.level !== 'senior' ? [...acc, val] : acc , []);
const lastJunior = intermediate.map(v => v.level).lastIndexOf('junior');
const seniors = arr.filter(v => v.level === 'senior');
const finalArr = [
    ...intermediate.slice(0, lastJunior + 1), 
    ...seniors, 
    ...intermediate.slice(lastJunior + 1) ];

document.querySelector('pre').textContent = JSON.stringify(finalArr, null, 2);

// shorter alternativeconst [seniorLevels, reshuffled] = arr.reduce( (acc, val) =>
  acc[val.level === 'senior' ? 0 : 1].push(val) && acc, [[], []]);

// reinsert
reshuffled.splice(
  reshuffled.map(v => v.level).lastIndexOf('junior') + 1,
  0, 
  ...seniorLevels);
document.querySelector('pre').textContent += `\n\nResult of alternative\n${
  JSON.stringify(reshuffled, null, 2)}`;
<pre></pre>

Solution 4:

You could iterate from the end and check if the wanted item is found after you want to insert an iten.

const
    array = [{ level: 'mid' }, { level: 'senior', x: 1 }, { level: 'junior' }, { level: 'senior', x: 2 }, { level: 'mid' }, { level: 'junior' }, { level: 'entry' }],
    item = 'senior',
    after = 'junior',
    result = array.reduceRight((offset =>(r, o, i, a) => {
        if (offset === -1 && o.level === after) offset = a.length - 1 - i;
        if (offset !== -1 && o.level === item) r.splice(r.length - offset++, 0, o);
        else r.unshift(o);
        return r;
    })(-1), []);

console.log(result);
.as-console-wrapper { max-height: 100%!important; top: 0; }

Post a Comment for "Custom Sort Between Two Values"