Вопрос

У меня есть данные в байтах.Мне нужно нарисовать эти значения в виде понятных человеку меток на диаграмме (например, 2,5 КБ, 14 МБ и т. д.) и помочь с функцией (входные данные — фактическое значение, выходные данные — удобочитаемая строка).

Я так и работал, но хочу более элегантную реализацию

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]
    }
}
Это было полезно?

Решение

Мне нравится эта реализация: ясная и компактная:

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];
}

Применение:

readablizeBytes(10000000)
"9.54 MB"

Я не принимаю кредит на это.

Другие советы

Это то, что я использую. Он подходит к ближайшему блоку, поэтому 1000 - «0,98 КБ», если вы этого не хотите, затем измените первую математику на пол.

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';
}

Возможно, что -то вроде этого?

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';
}

РЕДАКТИРОВАТЬ

Хорошо, так как вы хотите что -то более элегантное, я полагаю, вы думаете о цикле. Может быть, это подойдет вашим потребностям:

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];
}

Здесь я предположил type был логическим - изменить то, что вам подходит лучше всего.

Модифицированная версия 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"

С:

  • Суффиксы МЭК
  • Нет нестандартных суффиксов
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';
}

Тест:

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

Выход:

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

Я взял то, что мне показалось лучшим из двух лучших решений, и придумал это: оно быстрее, чем первое, и медленнее, чем второе.Но его цель — всегда иметь ровно 3 символа, а не круглые.Причина ограничения в 3 символа заключалась в ограничениях размера контейнера, в который он помещался.Кроме того, если вы захотите использовать его для форматирования чисел, отличных от базы 2, все, что вам нужно сделать, это изменить килограмм на 1000.Также происходит короткое замыкание, если число меньше 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;
};

Вы ответы действительно помогли мне, поэтому я решил написать метод утилиты, который раз и навсегда решает эту проблему форматирования размера.

Проверьте мою страницу jsutils repo wiki: https://bitbucket.org/aaverin/jsutils/ | https://github.com/aaverin/jsutilsОно имеет HumanReadeableSize Метод, который использует способ окружения размера Амира, но также поддерживает преобразование между обычным основанием 2 (KIB, MIB) и базовыми числами 10 (KB, MB).

Он может вниз до ближайшего значения, но также и окружить, если вы хотите, например, получить, сколько KB находится в PB.

Не стесняйтесь захватывать его и использовать в своих проектах!

Может использовать номер_TO_HUMAN_SIZE (number, options = {})

number_to_human_size(1234567)

Примеры:

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

как в документации http://api.rubyonrails.org/classes/actionview/helpers/numberhelper.html#method-i-number_to_human_size

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top