Actual numbers to the human readable values

陌路散爱 提交于 2020-01-22 14:28:06

问题


I have data in bytes. I need to draw this values as human readable labels on a chart (like 2.5KB, 14MB etc.) and need to help with function (input data - actual value, output - human readable string).

I did funcion like this, but I want more elegant realization

function tickFormatter(value, type) {

    var suffix = (type == "bytes") ? ['B', 'KB', 'MB', 'GB'] : ['', 'K', 'M', 'G']

    if(value > (1024 * 1024 * 1024 * 1024)) {
        return (value / (1024 * 1024 * 1024 * 1024)).toFixed(2) + suffix[3]
    } else if(value > (1024 * 1024 * 1024)) {
        return (value / (1024 * 1024 * 1024)).toFixed(2) + suffix[2]
    } else if (value > (1024 * 1024)) {
        return (value / (1024 * 1024)).toFixed(2) + suffix[1]
    } else {
        return value.toFixed(2) + suffix[0]
    }
}

回答1:


I love this implementation: clear and compact:

function readablizeBytes(bytes) {
    var s = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'];
    var e = Math.floor(Math.log(bytes) / Math.log(1024));
    return (bytes / Math.pow(1024, e)).toFixed(2) + " " + s[e];
}

Usage:

readablizeBytes(10000000)
"9.54 MB"

I don't take the credit of this.




回答2:


This is what I use. It rounds up to the nearest unit, so 1000 is "0.98KB" If you don't want that, then change the first Math.round to a floor.

var SizePrefixes = ' KMGTPEZYXWVU';
function GetHumanSize(size) {
  if(size <= 0) return '0';
  var t2 = Math.min(Math.round(Math.log(size)/Math.log(1024)), 12);
  return (Math.round(size * 100 / Math.pow(1024, t2)) / 100) +
    SizePrefixes.charAt(t2).replace(' ', '') + 'B';
}



回答3:


Perhaps something like this?

function readable (nb_bytes) {
    if (nb_bytes < 1024) return nb_bytes + 'B';
    else if (nb_bytes < 1024 * 1024) return (Math.round((nb_bytes / 1024) * 100) / 100) + 'KB';
    else return (Math.round((nb_bytes / 1024 / 1024) * 100) / 100) + 'MB';
}

[EDIT]

Alright, since you want something more elegant, I assume you're thinking of a loop. Maybe this will suit your needs:

function readable (nb_bytes,type) {
    var suffix = type ? ['B','KB','MB','GB'] : ['','K','M','G'];
    var i = 0;
    while (nb_bytes > 1024 && i < suffix.length - 1) {
        ++i;
        nb_bytes = Math.round((nb_bytes / 1024) * 100) / 100;
    }
    return (nb_bytes) + suffix[i];
}

Here I assumed type was a boolean - change to whatever suits you best.




回答4:


Modified version of Amer's:

(function GetHumanSize(size) {
  var SizePrefixes = ['','K','M','G','T','P','E','Z','Y'];
  if(size <= 0) return '0';
  var t2 = Math.min(Math.round(Math.log(size)/Math.log(1024)),
                    SizePrefixes.length-1);
  return String((Math.round(size * 100 / Math.pow(1024, t2)) / 100)) + 
         ' ' + SizePrefixes[t2] + 'iB';
})(Math.pow(2,131)) === "2251799813685248 YiB"

With:

  • IEC suffixes
  • No non-standard suffixes



回答5:


function formatSize(size, standard) {
    if (standard) { 
        standard = standard.toLowerCase();
    }

    var n = 0, 
        base = standard == 'si' ? 1000 : 1024, 
        prefixes = ' KMGTPEZY';

    if (size < 1) {
        return 0;
    }
    else if (size >= base) {
        n = Math.floor( Math.log(size) / Math.log(base) );

        if (n >= prefixes.length) {
            return 'N/A';
        }

        size = ( size / Math.pow(base, n) ).toFixed(2) * 1 + ' ';
    }

    return size + prefixes[n] + ( n && standard == 'iec' ? 'i' : '' ) + 'B';
}

Test:

for (var i = 0; i++ < 10;) console.log( formatSize( Math.pow(10, i) ) ); 

Output:

10 B
100 B
1000 B
9.77 KB
97.66 KB
976.56 KB
9.54 MB
95.37 MB
953.67 MB
9.31 GB



回答6:


I took what I felt the best of the top two solutions and came up with this, its faster than the first, slower than the second. But its purpose is to always have exactly 3 characters, and not round. The reason for the 3 character limit was due to size constraints for the container it was being placed into. Additionally should you want to use it to format non base 2 numbers all you need to do is change kilo to 1000. It also short circuits if the number is under 1k

var kilo = 1024, suffix = ' KMGTPEZYXWVU', humanReadable = function (number) {
  var retValue = false;
  if (typeof number == "number") {
      if (number < kilo) {
          retValue = number.toString();
      } else {
          var e = Math.floor(Math.log(number) / Math.log(kilo));
          retValue = Number((number / Math.pow(kilo, e)).toString().slice(0, 3)) + suffix.charAt(e) + 'B';
      }
  }
  return retValue;
};



回答7:


You answers really helped me, so I decided to write an utility method that solves this problem of size formatting once and for all.

Check out my JSUtils repo wiki page: https://bitbucket.org/AAverin/jsutils/ | https://github.com/AAverin/JSUtils It has humanReadeableSize method that uses Amir's way of rounding the size, but also supports conversion between the usual base of 2 (KiB, MiB) and base 10 numbers (KB, MB).

It can round down to the closest value, but also round up in case you want, for example, get how much KB are in PB.

Feel free to grab it and use in your projects!




回答8:


Could use number_to_human_size(number, options = {})

number_to_human_size(1234567)

examples:

number_to_human_size(123)                                          # => 123 Bytes
number_to_human_size(1234)                                         # => 1.21 KB
number_to_human_size(12345)                                        # => 12.1 KB
number_to_human_size(1234567)                                      # => 1.18 MB
number_to_human_size(1234567890)                                   # => 1.15 GB
number_to_human_size(1234567890123)                                # => 1.12 TB
number_to_human_size(1234567, precision: 2)                        # => 1.2 MB
number_to_human_size(483989, precision: 2)                         # => 470 KB
number_to_human_size(1234567, precision: 2, separator: ',')        # => 1,2 MB

as in documentation http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_to_human_size



来源:https://stackoverflow.com/questions/4498866/actual-numbers-to-the-human-readable-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!