Search code examples
javascriptarraysparsingcomparisonstring-parsing

What are ways of comparing number values where some come in the form of e.g. '32k' or '2.5m'


Is there a standard way in JavaScript to easily compare two numbers where one or both can be in the form of e.g. '32k'. For example:

'32k' > 310
'2.5k' > 450
300 > 200
'2.5m' > '2.5k'

So that one easily could find the max value of an array like ... [300, '3k', '3.2k']. I could try to create my own function but I wondered if there is a standard way to do this?


Solution

  • If you have 'k', or 'm', then the "number" is actually a string object, so you would need to parse out the number before you could do a comparison. Since you are only looking for the max value, a simple loop, parse, convert, and compare should be sufficient. Here is an example that supports 'k', 'm', 'b', 't' (case insensitive).

    //Using a simple object for fast lookups of mutliplier.
    const abvMap = {
      'k': 1000,
      'm': 1000000,
      'b': 1000000000,
      't': 1000000000000
    };
    
    function getMaxIndex(numArray) {
      if (!numArray || !Array.isArray(numArray) || numArray.length === 0) {
        throw 'invalid input';
      }
    
      //Start with the first number being the 
      let maxValue = parseNumber(numArray[0]);
      let maxIdx = 0;
    
      for (let i = 1, len = numArray.length; i < len; i++) {
        let num = parseNumber(numArray[i]);
    
        if (num > maxValue) {
          maxValue = num;
          maxIdx = i;
        }
      }
    
      return maxIdx;
    }
    
    function parseNumber(numString) {
      //Check to see if input is a number already. If so, return it.
      if (typeof numString === 'number') {
        return numString;
      }
    
      //Capture the number by removing any letters, $ sign (make it more reusable)
      let num = parseFloat(numString.replace(/[a-zA-Z$]/gi, ''));
    
      //Capture the number abbreviation. 
      let abv = numString.replace(/[-$\d.\s]*/gi, '');
    
      if (abv) {
        //Normalize abbreviation.
        abv = abv.toLowerCase();
    
        //Get the multiplier.
        let multiplier = abvMap[abv];
    
        if (multiplier) {
          //Multiply the value accordingly.
          return num * multiplier;
        }
      }
    
      return num;
    }
    
    function getMaxValue(numArray) {
      //Get the index of the max value, then return that value from the array.
      return numArray[getMaxIndex(numArray)];
    }
    
    //Test array of mixed number values.
    var myArray = ['300', '3k', '3.2k', '0.0001k', '$15', '$30k', 1000];
    
    
    document.body.innerHTML = getMaxValue(myArray);