0
data = [{"map_name": "PHX7260.AE5020003.9"}, 
        {"map_name": "PHX7260.AE5020003.10"}, 
        {"map_name": "PHX7260.AE5020003.1"}]

I want to sort this data in descending order alphabetically and numerically both.

I tried the below but it doesn't work on array of objects.

var myArray  = data;
var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
console.log(myArray.sort(collator.compare));

How should I go about it, the data of objects is received and it should be returned as objects only and not as array to display.

Robotnicka
  • 554
  • 1
  • 10
  • 20
shweta
  • 9
  • 6

3 Answers3

1

You can use array#sort with string#localeCompare with numeric property set to true.

const data = [{"map_name": "PHX7260.AE5020003.9"}, {"map_name": "PHX7260.AE5020003.10"},{"map_name": "PHX7260.AE5020003.1"}];
data.sort((a,b) => b.map_name.localeCompare(a.map_name, undefined, {numeric: true}));
console.log(data);
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51
  • This is the proper way to do this. I always forget that `localeCompare` is a thing, very nice. – jmcgriz Mar 19 '18 at 14:36
  • This approach is not sorting according to the OP's statement. Even doesn't follow this *also since PHX7260.AE5020003 are same hence the output expected is above , if the string aredifferent it should sort the string first and then the number* – Ele Mar 19 '18 at 14:43
  • Thanks @Ele. Updated the solution. – Hassan Imam Mar 19 '18 at 14:45
  • breaks at error: Cannot read property 'localeCompare' of undefined – shweta Mar 20 '18 at 07:10
  • It means that one of the objects doesn't have `map_name` property. – Hassan Imam Mar 20 '18 at 07:16
0
  • You can get the string and the number before/after the last dot respectively.

  • Compare the string first, if they are equal sort by number else use the function localeCompare.

This approach sorts using descending direction.

Look how ZHX7260.AE5020003.10 is placed at the first position.

var data = [{"map_name": "PHX7260.AE5020003.9"},        {"map_name": "ZHX7260.AE5020003.10"},        {"map_name": "PHX7260.AE5020003.10"},        {"map_name": "PHX7260.AE5020003.1"}];
        
data.sort((a, b) => {
  var astr = a.map_name.substring(0, a.map_name.lastIndexOf('.'));
  var bstr = b.map_name.substring(0, b.map_name.lastIndexOf('.'));
  
  if (astr === bstr) {
    var aidx = a.map_name.substring(a.map_name.lastIndexOf('.') + 1);
    var bidx = b.map_name.substring(b.map_name.lastIndexOf('.') + 1);
    
    return bidx - aidx;
  } else return bstr.localeCompare(astr);
}); 

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
also since PHX7260.AE5020003 are same hence the output expected is above , if the string aredifferent it should sort the string first and then the number
Ele
  • 33,468
  • 7
  • 37
  • 75
0

Using javascript's native Array.sort() method, you can split your strings on . and do a multi-step sort like below:

var data = [{"map_name": "PHX7260.AE5020003.9"}, 
        {"map_name": "PHX7260.AE5020003.10"}, 
        {"map_name": "PHX7260.AE5020003.1"}]
    
function compare(a,b){
  if(!!parseInt(a) && !!parseInt(b)){
    a = parseInt(a)
    b = parseInt(b)
  }
  if(a > b) return 1
  else if(a < b) return -1
  else return 0
}
    
function sortData(a,b){
  let a_arr = a.map_name.split('.'),
    b_arr = b.map_name.split('.')
    
  while(a_arr.length){
    let val = compare(a_arr.shift(), b_arr.shift())
    if(val) return val
  }
  
  return 0
}

console.log(data.sort(sortData))
jmcgriz
  • 2,819
  • 1
  • 9
  • 11