Simple Pretty-Bytes Size (SI System) Using the STM Method
Tags: javascript, node
Published: 2020-07-20 11:44:33

Displaying bytes in the SI Scaling System is useful for displaying file sizes in a human-readable format. Also known as "Pretty Bytes".

This post explains how this can be done using a simple **String-Triplet-Map** Method in javascript under the SI Decimal System for quantifying bytes.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/z79enm5or2wxc7feg8ke.png)

The code does not use complex maths such as Math.pow() or Math.log() and mainly uses strings with an array.

The function uses the ***SI system of decimals*** as shown below (1 kilo = 1,000, 1 M = 1,000,000, etc.).

The code is short and uses the method of Number String Triplets to first convert the input number (the integer) into a Number String Triplet, then into an array of Triplets.

The following one-line code is used for converting an integer into a **Number String Triplet** so that the resulting string will always be made of multiple of 3's by padding zero(s) to the left. 

```javascript
Num = "0".repeat((Num += "").length * 2 % 3) + Num;
```
With the above line of code, any number may be converted into a String Triplet (so the length is always a multiple of 3 digits), for example:

`1234` will become `001234`
`12345` will become `012345`
`1230000` will become `001230000`

We can then simply convert the number string into an `array` of Triplets. To do that, a simple **regex** will do that for us:

```javascript
Num = Num.match(/.{3}/g);
```

So (for example) the number `1230000` after conversion into a String-Triplet as above will be converted into array elements and becomes:

```javascript
[001] , [123], [000]
```
The length of the array `array().length` is in fact the **Number Scale**.

In the above example, we have three (3) elements in the array, so the scale is `Millions` or `Mega (M)`.

```javascript
0 elements = 0 Scale
1 element  = Thousands (k)
2 elements = Millions  (M) Mega
3 elements = Billions  (G) Giga
4 elements = Trillions (T) Tera
.... etc.
```

In fact, the first element of the array `array[0]` is the number we are looking for. The 2nd element `array[1]` is what we can make as a fraction part. The rest of the array elements can simply be ignored. ***Note: It is also possible to create an array with only the 1st and 2nd triplets ignoring the remaining parts of the string.***

The output is then made up of concatenating the first element of the array being the whole number and the 2nd element being the fraction (after chopping off for decimals) and adding the suffix letter.

Numbers below 1000 do not require the functional code and are cleared out first.

The number of decimal places is defaulted to 2 (no rounding is necessary) but can be modified on calling the function to other values. The common most used display is the default 2 decimal place.

If there is a possibility that the input number may be a float, it should be converted to an integer first Num = Math.floor(Num); before passing it to the function.

As the code is mainly for displaying size, no code is added for handling negative numbers or floats (not sure if one would give a size as '3 and a half byte').

```javascript
/***************************************************************
    * @function    : numberPrettyBytesSI()
    * @purpose     : Convert number bytes size to human readable format
    *                using the SI Decimal System.
    * @version     : 1.00
    * @author      : Mohsen Alyafei
    * @date        : 01 July 2020
    * @param       : {num}      [integer] Number to be converted
    * @param       : {decimals} [integer] Deciaml places (defaul 2)
    * @returns     : {String}   Pretty Number
****************************************************************/
function numberPrettyBytesSI(Num=0, decimals=2){
if (Num < 1000) return Num + " Bytes";
Num = "0".repeat((Num +="").length * 2 % 3) + Num; // Make a Number String Triplet
Num = Num.match(/.{3}/g);    // Make an Array of Triplets
return Number(Num[0]) +      // Whole Number without leading zeros
 "." +                                  // Add a dot
 Num[1].substring(0, decimals) + " " +  // Add fractional part
 "  kMGTPEZY"[Num.length] + "B";        // Add SI suffix
}





//*********** example tests ***********************
console.log(numberPrettyBytesSI(0));            // 0 Bytes
console.log(numberPrettyBytesSI(500));          // 500 Bytes
console.log(numberPrettyBytesSI(1000));         // 1.00 kB
console.log(numberPrettyBytesSI(15000));        // 15.00 kB
console.log(numberPrettyBytesSI(12345));        // 12.34 Kb
console.log(numberPrettyBytesSI(123456));       // 123.45 kb
console.log(numberPrettyBytesSI(1234567));      // 1.23 MB
console.log(numberPrettyBytesSI(12345678));     // 12.34 MB
console.log(numberPrettyBytesSI(123456789));    // 123.45 MB
console.log(numberPrettyBytesSI(1234567890));   // 1.23 GB
console.log(numberPrettyBytesSI(1234567890,1)); // 1.2 GB
console.log(numberPrettyBytesSI(1234567890,3)); // 1.234 GB
```

The code is also posted here on CodeReview StackExchange.

{% stackexchange 244903 codereview %}