Sort array of objects with dots, letters, numbers. I was able to sort by numbers, but mixed values are difficult. Not sure if possible to do it right

前端 未结 2 430
梦谈多话
梦谈多话 2021-01-17 20:10

I tried the typical sort function and checked if item is string. But I get a very strange output. Tried multiple different approaches.

 var arr = [{section:          


        
2条回答
  •  失恋的感觉
    2021-01-17 20:25

    I propose a completely different approach. We're going to modify your strings until they are sortable by localeCompare

    Here's how:

    // "12" sorts before "2", prefixing to "12" and "02" fixes this
    // (length should be bigger than your largest nr)
    var makeLength5 = prefixWithZero.bind(null, 5);
    
    // This function generates a string that is sortable by localeCompare
    var toSortableString = function(obj) {
      return obj.section
        .replace(/\./g, "z")            // Places `12A` before `12.` but after `12`
        .replace(/\d+/g, makeLength5);  // Makes every number the same length
    };
    
    var arr = [{section:"12.2.a"},{section:"12.2.b.iii"},{section:"12.2.c"},{section:"12"},{section:"12A"},{section:"12.3.b"},{section:"12.3.c"},{section:"Q2"},{section:"Q32"},{section:"Q6"},{section:"Q5"}];
    var arr2 = arr.sort(function(a, b) {
      return toSortableString(a).localeCompare(toSortableString(b));
    });
    
    console.log(JSON.stringify(arr2.map(function(s){ return s.section; }), null, 2));
    
    // Helper methods
    function prefixWithZero(length, str) {
      while (str.length < length) {
        str = "0" + str;
      }
      return str;
    };

提交回复
热议问题