Home > Software engineering >  How to sort array of object by string of numbers and special characters
How to sort array of object by string of numbers and special characters

Time:02-02

I have an array of some objects and I want to sort them by dimension property, where that property is a string of some number intervals and special characters. Here is the example of what I have

let data = [
  {
    "soldTickets": 206,
    "soldRevenue": 12825.309997558594,
    "playedOffTickets": 2915,
    "playedOffRevenue": 495923.22019958496,
    "dimension": "10 - 25",
    "ticketsChange": -2709,
    "revenueChange": -483097.91020202637
  },
  {
    "soldTickets": 172,
    "soldRevenue": 17174.29998779297,
    "playedOffTickets": 2485,
    "playedOffRevenue": 467017.27951049805,
    "dimension": "25 - 50",
    "ticketsChange": -2313,
    "revenueChange": -449842.9795227051
  },
  {
    "soldTickets": 122,
    "soldRevenue": 9892.249984741211,
    "playedOffTickets": 9121,
    "playedOffRevenue": 1129196.3203125,
    "dimension": "> 200",
    "ticketsChange": -8999,
    "revenueChange": -1119304.0703277588
  },
  {
    "soldTickets": 52,
    "soldRevenue": 3159.239990234375,
    "playedOffTickets": 544,
    "playedOffRevenue": 88893.0400390625,
    "dimension": "0 - 10",
    "ticketsChange": -492,
    "revenueChange": -85733.80004882812
  },
  {
    "soldTickets": 38,
    "soldRevenue": 3162.1099700927734,
    "playedOffTickets": 476,
    "playedOffRevenue": 92432.79023742676,
    "dimension": "100 - 200",
    "ticketsChange": -438,
    "revenueChange": -89270.68026733398
  },
  {
    "soldTickets": 37,
    "soldRevenue": 3233,
    "playedOffTickets": 590,
    "playedOffRevenue": 97645.46026611328,
    "dimension": "50 - 100",
    "ticketsChange": -553,
    "revenueChange": -94412.46026611328
  }
];

const toNumber = (str) => {
  if (Number(str)) {
    return Number(str);
  } else {
    return Number(str.substring(0, str.length - 1));
  }
};

   data = data.sort(
        (a, b) =>
          toNumber(String(a["dimension"]).split(' ')[0]) -
          toNumber(String(b["dimension"]).split(' ')[0])
      );
      
  console.log(data)

The problem is that the array is not sorted the way I wanted, since the > 200 should be the last in this case instead of being the first. The desired order should be like this

['0 - 10', '10 - 25', '25 - 50', '50 - 100', '100 - 200', '> 200']

What am I doing wrong? Thanks in advance!

CodePudding user response:

If we can assume the first number is what we want to sort on, you can use a little regex to find the first number, and then we can sort on that.

Of course if your condition gets more complicated, like < 20 etc, then you would need to re-evaluate how you decide the ordering.

eg.

let data=[{soldTickets:206,soldRevenue:12825.309997558594,playedOffTickets:2915,playedOffRevenue:495923.22019958496,dimension:"10 - 25",ticketsChange:-2709,revenueChange:-483097.91020202637},{soldTickets:172,soldRevenue:17174.29998779297,playedOffTickets:2485,playedOffRevenue:467017.27951049805,dimension:"25 - 50",ticketsChange:-2313,revenueChange:-449842.9795227051},{soldTickets:122,soldRevenue:9892.249984741211,playedOffTickets:9121,playedOffRevenue:1129196.3203125,dimension:"> 200",ticketsChange:-8999,revenueChange:-1119304.0703277588},{soldTickets:52,soldRevenue:3159.239990234375,playedOffTickets:544,playedOffRevenue:88893.0400390625,dimension:"0 - 10",ticketsChange:-492,revenueChange:-85733.80004882812},{soldTickets:38,soldRevenue:3162.1099700927734,playedOffTickets:476,playedOffRevenue:92432.79023742676,dimension:"100 - 200",ticketsChange:-438,revenueChange:-89270.68026733398},{soldTickets:37,soldRevenue:3233,playedOffTickets:590,playedOffRevenue:97645.46026611328,dimension:"50 - 100",ticketsChange:-553,revenueChange:-94412.46026611328}];

data = data.sort(
  (a, b) =>
    (a.dimension.match(/\d /)[0] | 0) -
    (b.dimension.match(/\d /)[0] | 0)
);
      
console.log(data)

ps. the val | 0, is just a quick way to convert a string into a number, similar to Number(val), parseInt(val, 10) , if we don't convert to number, you would have 200 been less than 30 etc.

  •  Tags:  
  • Related