1

I am trying to make a simple 1000 to k convertor function in JS that will take a number and convert it into thousands/k. I'm having trouble getting the .toFixed(1) working properly. I don't want it to round up and I want it to show one decimal place UNLESS that decimal is a 0. A few examples of the returns I am looking to produce are:

1100 -> 1.1K

1199 -> 1.1K

9999 -> 9.9K

10900 -> 10.9K

10999 -> 10.9K

JS

   function kConvertor(num) {
     return num <= 999 ? num : (num/1000).toFixed(1) + 'k'
    }

This returns 10.0k which hits both cases that I do not want (9.9k). What am I doing wrong here?

I tried adding a parseInt() and .replace('.0', '') to the end and that didn't work.

   function kConvertor(num) {
      return num <= 999 ? num : parseInt((num/1000)).toFixed(1).replace('.0', '') + 'k'
   }

This just returns 9k

LovelyAndy
  • 841
  • 8
  • 22
  • 2
    `parseInt` won't return values with decimal places. – Alnitak Apr 06 '21 at 15:19
  • Remove the parseInt from the second example and it works just fine --- Also `10999` _should_ return 11K because it will be rounded up. – evolutionxbox Apr 06 '21 at 15:21
  • The OP says they don't want it to. However `.toFixed` will always use natural rounding, because it's intended for *presentation* purposes, not actual rounding. – Alnitak Apr 06 '21 at 15:24
  • 1
    having 9999 return 9.9k but 10999 return 10k (instead of 10.9k) is highly inconsistent and likely prevents any one line answers from producing the desired results. – Alnitak Apr 06 '21 at 15:26
  • @Alnitak Thank you for the reply! I only used parseInt because that was the only thing I could see that would not round up. In regards to the 10999 not rounding up, this is the result I wanted intially, but your comment made me think twice. Edited! Cheers – LovelyAndy Apr 06 '21 at 15:35
  • https://stackoverflow.com/questions/4187146/truncate-number-to-two-decimal-places-without-rounding – epascarello Apr 06 '21 at 15:39

1 Answers1

1

This works by using math operators to correctly round down to the nearest 10th of a K, and then uses .toFixed(1) to perform the string manipulation necessary to strip .0 from the result:

function kConverter(num) {
    return num <= 999 ? num : (0.1 * Math.floor(num / 100)).toFixed(1).replace('.0','') + 'k'
}

NB: it's not good practise to have the function return a number for <= 999, or a string otherwise. Unexpected result types is the cause of the vast majority of the "WAT?!" moments from the famous video. Always ensure that your return types are consistent:

function kConverter(num) {
    if (num < 1000) {
        return number.toFixed(0);   // assuming an integer
    } else {
        const s = (0.1 * Math.floor(num / 100)).toFixed(1);
        return s.replace('.0', '') + 'k';
    }
}
Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • Thank you for the answer here! If it's not too much trouble to ask, why is it not good practice to return num if it's less than 999? I am trying to display any number there, just converting thousands to k when it gets that high. I still want the number to show. – LovelyAndy Apr 06 '21 at 15:43
  • @LovelyAndy see text added to the end of the answer. It's the _types_ that matter. Consider hypothetically what happens if you write `10 + kConverter(n)`. For 999 it'll produce 1009, but for 1009 it'll produce 1010k, because the `+` operator does different things depending on the types of the two operands. – Alnitak Apr 06 '21 at 15:46
  • Thanks for the explanation! Where I'm using this in my app I don't think that will come up, but that's really good to know. I'm still quite new in this field so these sort of gotcha cases (especially the 10.9k point) are good to know! I appreciate all of your help today! – LovelyAndy Apr 06 '21 at 15:53