0

Considering that I have an object like the following where it's possible to have many names and that 'The others' can appear at any index, how can I sort the array having 'The others' always as the first element and the rest of the names sorted in alphabetical order?

var friends = [
{ id: 1, name: 'Paul' },
{ id: 2, name: 'Mary' },
{ id: 3, name: 'The others' },
{ id: 4, name: 'John' }
];

For the sample array above, the desired result would be:

[
   { id: 3, name: 'The others' }, 
   { id: 4, name: 'John' }, 
   { id: 2, name: 'Mary' }, 
   { id: 1, name: 'Paul' }
]
Vinicius Santana
  • 3,936
  • 3
  • 25
  • 42

7 Answers7

4

Simply check for either value in the sort callback being The others - return -1 if a is that, or 1 if it's b - otherwise return the localeCompare of a and b

friends.sort(({name: a}, {name:b}) => a == "The others" ? -1 : (b == "The others" ? 1 : a.localeCompare(b)));

The "readable" and non-ES2015+ version of that

friends.sort(function (a, b) {
  if (a.name == "The others") return -1;
  if (b.name == "The others") return 1;
  return a.name.localeCompare(b.name);
});
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
2

Sort like this:

var friends = [
   { id: 1, name: 'Paul' },
   { id: 2, name: 'Mary' },
   { id: 3, name: 'The others' },
   { id: 4, name: 'John' }
];

friends.sort((a, b) => {
     if (a.name == "The others") {
         return -1; // a comes first
     } else if (b.name == "The others") {
         return 1;
     } else {
         return (a.name < b.name ? -1 : 1);
     }
 });

console.log(friends);
Daniel Tran
  • 6,083
  • 12
  • 25
1

Following are steps that you need to follow

  1. Sort : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
  2. Move : Move an array element from one array position to another

Please see following working example.

var friends = [{
    id: 1,
    name: 'Paul'
  },
  {
    id: 2,
    name: 'Mary'
  },
  {
    id: 3,
    name: 'The others'
  },
  {
    id: 4,
    name: 'John'
  }
];

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
friends.sort(function(a, b) {
  var nameA = a.name.toUpperCase(); // ignore upper and lowercase
  var nameB = b.name.toUpperCase(); // ignore upper and lowercase
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }

  // names must be equal
  return 0;
});

var indexOfTheOters = friends.reduce(function(acc, friend, index) {
  if(!acc && friend.name === 'The others') {
    acc = index;
  }
  return acc;
}, null);

// https://stackoverflow.com/questions/5306680/move-an-array-element-from-one-array-position-to-another
Array.prototype.move = function (old_index, new_index) {
    if (new_index >= this.length) {
        var k = new_index - this.length;
        while ((k--) + 1) {
            this.push(undefined);
        }
    }
    this.splice(new_index, 0, this.splice(old_index, 1)[0]);
    return this; // for testing purposes
};
friends.move(indexOfTheOters, 0)
console.log(friends);
Vipin Kumar
  • 6,441
  • 1
  • 19
  • 25
1

Try the following:

var friends = [
{ id: 1, name: 'Paul' },
{ id: 2, name: 'Mary' },
{ id: 3, name: 'The others' },
{ id: 4, name: 'John' }
];
var notConsidered = friends.filter(friend => friend.name == 'The others');
var friend = friends.filter(friend => friend.name!= 'The others');
var sortedfriend = friend.sort(function (a, b) {
  if (a.name < b.name) return -1;
  else if (a.name > b.name) return 1;
  return 0;
});

sortedfriend.unshift(notConsidered[0])
console.log(sortedfriend);
Mamun
  • 66,969
  • 9
  • 47
  • 59
1
  1. copy your (The others object) and store it into a variable using filter
  2. remove it from the array using filter
  3. sort the array by name property.
  4. add the (The others object) in the beginning of your array using unshift

compare function copied from this answer

var friends = [{
        id: 1,
        name: 'Paul'
    },
    {
        id: 2,
        name: 'Mary'
    },
    {
        id: 3,
        name: 'The others'
    },
    {
        id: 4,
        name: 'John'
    }
];


function compare(a,b) {
    if (a.name < b.name)
      return -1;
    if (a.name > b.name)
      return 1;
    return 0;
  }


// copy the others object
const theOthersObj = friends.filter(friend => friend.name === 'The others')[0];

const newFriends = friends
            .filter(friend => friend.name !== 'The others') // removing the others object
            .sort(compare) // storing the array by name
// Adding the others object in the first of the array
newFriends.unshift(theOthersObj);

console.log(newFriends);
Mohamed Abbas
  • 2,228
  • 1
  • 11
  • 19
1

You want to hard code your compare function so that 'The others' always has the lowest/greatest value.

var friends = [
{ id: 1, name: 'Paul' },
{ id: 2, name: 'Mary' },
{ id: 3, name: 'The others' },
{ id: 4, name: 'John' }
];

function compare(a, b){
  if(a.name === "The others") {
   return -1;
  } else if (b.name === "The others") {
   return 1;
  } else if (a.name > b.name){
   return -1;
  } else if (a.name < b.name){
   return 1;
  } else {
   return 0;
  }
}

console.log(friends.sort(compare))
Jeremy Myers
  • 159
  • 6
0

There are some great ideas here but what I found to be the simpler solutions are the two bellow:

Using sort:

friends.sort((a, b) => a.name !== b.name ? a.name < b.name ? -1 : 1 : 0).sort((a, b) => +(!b.name.localeCompare("The others")));

Using map and sort:

friends.map(o => o.name).sort((a,b) => a=="The others" ? -1 : b=="The others" ? 1 : a > b);
Vinicius Santana
  • 3,936
  • 3
  • 25
  • 42