Formatez un nombre en 2,5K si mille ou plus, sinon 900


154

Je dois afficher une valeur de devise au format 1K égale à mille, ou 1,1K, 1,2K, 1,9K, etc., si ce n'est pas un millier pair, sinon si elle est inférieure à mille, affichez la normale 500, 100, 250, etc. , en utilisant javascript pour formater le nombre?


2
Avez-vous également besoin de Met G?
Salman A

J'aurai besoin de M oui ... Pouvez-vous m'aider?
Carl Weis

Réponses:


209

Cela devrait fonctionner pour vous:

function kFormatter(num) {
    return Math.abs(num) > 999 ? Math.sign(num)*((Math.abs(num)/1000).toFixed(1)) + 'k' : Math.sign(num)*Math.abs(num)
}
    
console.log(kFormatter(1200)); // 1.2k
console.log(kFormatter(-1200)); // -1.2k
console.log(kFormatter(900)); // 900
console.log(kFormatter(-900)); // -900


2
Correction mineure suggérée ... Doit être un k minuscule pour des milliers. Upper est pour Kilos. Essayé de modifier, mais nécessite au moins 6 caractères modifiés avant de prendre.
Adam Youngers

Comment insérer une variable php ici et l'utiliser? c'est-à-dire si ma variable numérique est $mynumber_outputoù dois-je l'insérer pour l'utiliser? Par exemple, disons $mynumber_output= 12846, je voudrais que 12846 soit converti en12.8k

Notez qu'un kilo-octet
équivaut à

Une idée de la façon dont nous pouvons faire afficher 1000 comme 1.0k au lieu de 1k?
Brent

1
Ne répond pas complètement à la question de l'utilisateur. "J'aurai besoin de M oui ... Pouvez-vous m'aider?" - Carl Weis
tfmontague

217

Une version plus généralisée:

function nFormatter(num, digits) {
  var si = [
    { value: 1, symbol: "" },
    { value: 1E3, symbol: "k" },
    { value: 1E6, symbol: "M" },
    { value: 1E9, symbol: "G" },
    { value: 1E12, symbol: "T" },
    { value: 1E15, symbol: "P" },
    { value: 1E18, symbol: "E" }
  ];
  var rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
  var i;
  for (i = si.length - 1; i > 0; i--) {
    if (num >= si[i].value) {
      break;
    }
  }
  return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol;
}

/*
 * Tests
 */
var tests = [
  { num: 1234, digits: 1 },
  { num: 100000000, digits: 1 },
  { num: 299792458, digits: 1 },
  { num: 759878, digits: 1 },
  { num: 759878, digits: 0 },
  { num: 123, digits: 1 },
  { num: 123.456, digits: 1 },
  { num: 123.456, digits: 2 },
  { num: 123.456, digits: 4 }
];
var i;
for (i = 0; i < tests.length; i++) {
  console.log("nFormatter(" + tests[i].num + ", " + tests[i].digits + ") = " + nFormatter(tests[i].num, tests[i].digits));
}


@SalmanA - Grande aide, cela échoue si on passe arg en tant que chaîne, s'il est nettoyé avec parseFloat fonctionne bien. Je vous remercie!
Adesh M

1
Petite correction pour les nombres inférieurs à 1 000, ajoutez {value: 1E0, symbol: ""} à var si =
Dimmduh

1
@GiovanniAzua vient de remplacer if (num >= si[i].value)parif (Math.abs(num) >= si[i].value)
Salman A

que fait .replace(rx, "$1")-on?
M.Octavio

1
@ M.Octavio la regex est utilisée pour couper les zéros de fin, par exemple 1.0devient 1et 1.10devient1.1
Salman A

78

Voici une solution simple qui évite toutes les ifdéclarations (avec la puissance de Math).

var SI_SYMBOL = ["", "k", "M", "G", "T", "P", "E"];

function abbreviateNumber(number){

    // what tier? (determines SI symbol)
    var tier = Math.log10(number) / 3 | 0;

    // if zero, we don't need a suffix
    if(tier == 0) return number;

    // get suffix and determine scale
    var suffix = SI_SYMBOL[tier];
    var scale = Math.pow(10, tier * 3);

    // scale the number
    var scaled = number / scale;

    // format number and add suffix
    return scaled.toFixed(1) + suffix;
}

Bonus Meme

Que fait SI ?


J'aime vraiment ta solution. Pour pouvoir raccourcir également les valeurs négatives, je multiplie le nombre par -1 avant et après la détermination du niveau, car Math.log10 (valeur négative) renverrait NaN.
xhadon

Il suffit d' utiliser Math.abspour ajouter le support aux nombres négatifs, comme ça: var tier = Math.log10(Math.abs(number)) / 3 | 0;.
Caio Tarifa le

71

Amélioration de la réponse de Salman car elle renvoie nFormatter (33000) sous la forme 33.0K

function nFormatter(num) {
     if (num >= 1000000000) {
        return (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
     }
     if (num >= 1000000) {
        return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
     }
     if (num >= 1000) {
        return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
     }
     return num;
}

maintenant nFormatter (33000) = 33K


2
Quoi qu'il en soit, faire cela sans arrondir le nombre? 1,590,000 renverra 1,6M.
Brett Hardin

3
Parfois, il est difficile de savoir quand publier une nouvelle réponse ou modifier une réponse existante, quelque chose que j'utilise pour décider est si je vole le code d'une autre réponse d'utilisateurs, je modifie généralement leur réponse afin qu'ils puissent obtenir la reconnaissance au lieu que je vole leur code.
MH le

@Yash, vous êtes le code que j'essaie d'implémenter dans le script de compteur mais je ne l'obtiens pas, c'est mon lien codepen.io/Merajkhan/pen/MMoxGE?editors=1010 Pouvez-vous m'aider à mettre en œuvre cette logique que je veux Les unités K, L, M doivent venir.
Mehraj Khan

Génial. Solution courte et douce.
Hasitha Jayawardana

22
/**
 * Shorten number to thousands, millions, billions, etc.
 * http://en.wikipedia.org/wiki/Metric_prefix
 *
 * @param {number} num Number to shorten.
 * @param {number} [digits=0] The number of digits to appear after the decimal point.
 * @returns {string|number}
 *
 * @example
 * // returns '12.5k'
 * shortenLargeNumber(12543, 1)
 *
 * @example
 * // returns '-13k'
 * shortenLargeNumber(-12567)
 *
 * @example
 * // returns '51M'
 * shortenLargeNumber(51000000)
 *
 * @example
 * // returns 651
 * shortenLargeNumber(651)
 *
 * @example
 * // returns 0.12345
 * shortenLargeNumber(0.12345)
 */
function shortenLargeNumber(num, digits) {
    var units = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
        decimal;

    for(var i=units.length-1; i>=0; i--) {
        decimal = Math.pow(1000, i+1);

        if(num <= -decimal || num >= decimal) {
            return +(num / decimal).toFixed(digits) + units[i];
        }
    }

    return num;
}

Merci @Cos pour commentaire, j'ai supprimé la dépendance Math.round10.


1
Vous pouvez modifier le if en Math.abs(num) >= decimal.
Conor Pender

18

Beaucoup de réponses sur ce thread deviennent plutôt compliquées, en utilisant des objets Math, des objets de carte, des boucles for, des expressions régulières, etc. Mais ces approches n'améliorent pas vraiment la lisibilité du code ou les performances. Une approche simple semble offrir le meilleur design.

Formatage de la valeur en espèces avec K

const formatCash = n => {
  if (n < 1e3) return n;
  if (n >= 1e3) return +(n / 1e3).toFixed(1) + "K";
};

console.log(formatCash(2500));

Formatage de la valeur en espèces avec KMBT

const formatCash = n => {
  if (n < 1e3) return n;
  if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(1) + "K";
  if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(1) + "M";
  if (n >= 1e9 && n < 1e12) return +(n / 1e9).toFixed(1) + "B";
  if (n >= 1e12) return +(n / 1e12).toFixed(1) + "T";
};

console.log(formatCash(1235000));

Utiliser des nombres négatifs

let format;
const number = -1235000;

if (number < 0) {
  format = '-' + formatCash(-1 * number);
} else {
  format = formatCash(number);
}

1
@Jan - Mise à jour de mon message avec un exemple, mais j'ai trouvé que c'était assez simple pour calculer la forme négative en utilisant'-' + formatCash(-1 * number)
tfmontague

15

Donnez du crédit à Waylon Flinn si vous aimez ça

Cela a été amélioré par rapport à son approche plus élégante pour gérer les nombres négatifs et le cas ".0".

Moins vous avez de boucles et de cas «si», meilleure est l'OMI.

function abbreviateNumber(number) {
    var SI_POSTFIXES = ["", "k", "M", "G", "T", "P", "E"];
    var tier = Math.log10(Math.abs(number)) / 3 | 0;
    if(tier == 0) return number;
    var postfix = SI_POSTFIXES[tier];
    var scale = Math.pow(10, tier * 3);
    var scaled = number / scale;
    var formatted = scaled.toFixed(1) + '';
    if (/\.0$/.test(formatted))
      formatted = formatted.substr(0, formatted.length - 2);
    return formatted + postfix;
}

jsFiddle avec des cas de test -> https://jsfiddle.net/xyug4nvz/7/


1
Il y a toujours un bug ennuyeux: abbreviateNumber(999999) == '1000k'au lieu de '1M'. C'est parce que toFixed()arrondit également les nombres. Je ne sais pas comment le résoudre, cependant: /
Vitor Baptista

@VitorBaptista Si toFixed()arrondit le nombre de toute façon, vous pouvez aussi arrondir le nombre avant de l'envoyer à abbreviateNumber(), afin qu'il retourne à la 1Mplace de 1000k. Pas une solution, mais une solution de contournement.
forsureitsme

2
Si vous ne voulez pas d'arrondi, vous pouvez le faire après l'étape de mise à l'échelle:const floored = Math.floor(scaled * 10) / 10;
tybro0103

14

ES2020 ajoute la prise en charge de cela dans Intl.NumberFormatUtilisation de la notation comme suit:

console.log(Intl.NumberFormat('en-US', { notation: "compact" , compactDisplay: "short" }).format(987654321));

NumberFormat spécifications:

Notez que pour le moment, tous les navigateurs ne prennent pas en charge ES2020, vous aurez donc peut-être besoin de ce Polyfill: https://formatjs.io/docs/polyfills/intl-numberformat


Ce package est obsolète, veuillez donc utiliser ce lien: npmjs.com/package/@formatjs/intl-numberformat
Ammad Khalid

2
Remarque: Chrome prend en charge notationet, compactDisplaymais FireFox 77 et Safari 13.1 ne le prennent toujours pas en charge, vous aurez donc probablement besoin du polyfill.
Josh Unger le

Wow, Firefox vient d' ajouter le support pour cela dans la v. 78, semble-t-il. Bien sûr, dans 2 ans et plus, ce commentaire aura l'air stupide. : P (C'est drôle pour moi cependant parce que le code fonctionne pour moi mais il ne se convertit pas correctement, donc je vais devoir faire une mise à jour.)
Andrew

11

c'est assez élégant.

function formatToUnits(number, precision) {
  const abbrev = ['', 'k', 'm', 'b', 't'];
  const unrangifiedOrder = Math.floor(Math.log10(Math.abs(number)) / 3)
  const order = Math.max(0, Math.min(unrangifiedOrder, abbrev.length -1 ))
  const suffix = abbrev[order];

  return (number / Math.pow(10, order * 3)).toFixed(precision) + suffix;
}

formatToUnits(12345, 2)
==> "12.35k"
formatToUnits(0, 3)
==> "0.000"

4

Vous pouvez utiliser le package au format d3 inspiré du formatage de chaîne avancé Python PEP3101 :

var f = require('d3-format')
console.log(f.format('.2s')(2500)) // displays "2.5k"

3

Améliorer encore la réponse de @ Yash avec la prise en charge des nombres négatifs:

function nFormatter(num) {
    isNegative = false
    if (num < 0) {
        isNegative = true
    }
    num = Math.abs(num)
    if (num >= 1000000000) {
        formattedNumber = (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
    } else if (num >= 1000000) {
        formattedNumber =  (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
    } else  if (num >= 1000) {
        formattedNumber =  (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
    } else {
        formattedNumber = num;
    }   
    if(isNegative) { formattedNumber = '-' + formattedNumber }
    return formattedNumber;
}

nFormatter(-120000)
"-120K"
nFormatter(120000)
"120K"

3

Ce message est assez ancien mais j'ai en quelque sorte atteint ce message à la recherche de quelque chose. Donc, pour ajouter mon entrée Numeral js est la solution à guichet unique maintenant quelques jours. Il donne un grand nombre de méthodes pour aider à formater les nombres

http://numeraljs.com/


1
numeraljs n'est plus maintenu. La fourche la plus active semble être numbro . Mais aucun d'eux ne supporte la notation SI / métrique
Vincent de Lagabbe

2

Méthode courte et générique

Vous pouvez rendre l' COUNT_FORMATSobjet de configuration aussi long ou court que vous le souhaitez, en fonction de la plage de valeurs que vous testez.

// Configuration    
const COUNT_FORMATS =
[
  { // 0 - 999
    letter: '',
    limit: 1e3
  },
  { // 1,000 - 999,999
    letter: 'K',
    limit: 1e6
  },
  { // 1,000,000 - 999,999,999
    letter: 'M',
    limit: 1e9
  },
  { // 1,000,000,000 - 999,999,999,999
    letter: 'B',
    limit: 1e12
  },
  { // 1,000,000,000,000 - 999,999,999,999,999
    letter: 'T',
    limit: 1e15
  }
];
    
// Format Method:
function formatCount(value)
{
  const format = COUNT_FORMATS.find(format => (value < format.limit));

  value = (1000 * value / format.limit);
  value = Math.round(value * 10) / 10; // keep one decimal number, only if needed

  return (value + format.letter);
}

// Test:
const test = [274, 1683, 56512, 523491, 9523489, 5729532709, 9421032489032];
test.forEach(value => console.log(`${ value } >>> ${ formatCount(value) }`));


1

En ajoutant la première réponse, cela donnera 1k pour 1000 au lieu de 1,0k

function kFormatter(num) {
    return num > 999 ? num % 1000 === 0 ? (num/1000).toFixed(0) + 'k' : (num/1000).toFixed(1) + 'k' : num
}

1

Une version modifiée de la réponse de Waylon Flinn avec prise en charge des exposants négatifs:

function metric(number) {

  const SI_SYMBOL = [
    ["", "k", "M", "G", "T", "P", "E"], // +
    ["", "m", "μ", "n", "p", "f", "a"] // -
  ];

  const tier = Math.floor(Math.log10(Math.abs(number)) / 3) | 0;

  const n = tier < 0 ? 1 : 0;

  const t = Math.abs(tier);

  const scale = Math.pow(10, tier * 3);

  return {
    number: number,
    symbol: SI_SYMBOL[n][t],
    scale: scale,
    scaled: number / scale
  }
}

function metric_suffix(number, precision) {
  const m = metric(number);
  return (typeof precision === 'number' ? m.scaled.toFixed(precision) : m.scaled) + m.symbol;
}

for (var i = 1e-6, s = 1; i < 1e7; i *= 10, s *= -1) {
  // toggles sign in each iteration
  console.log(metric_suffix(s * (i + i / 5), 1));
}

console.log(metric(0));

Production attendue:

   1.2μ
 -12.0μ
 120.0μ
  -1.2m
  12.0m
-120.0m
   1.2
 -12.0
 120.0
  -1.2k
  12.0k
-120.0k
   1.2M
{ number: 0, symbol: '', scale: 1, scaled: 0 }

1
  • Soutenir le nombre négatif
  • Recherche de !Number.isFinite
  • Changez ' K M G T P E Z Y'pour ' K M'si vous voulez que l'unité maximale soitM

Le code ci-dessous est 1K = 1024, si vous voulez 1K = 1000, changez tous les 1024 en 1000.


Number.prototype.prefix = function (precision = 2) {

    var units = ' K M G T P E Z Y'.split(' ');

    if (this < 0) {
        return '-' + Math.abs(this).prefix(precision);
    }

    if (this < 1) {
        return this + units[0];
    }

    var power = Math.min(
        Math.floor(Math.log(this) / Math.log(1024)),
        units.length - 1
    );

    return (this / Math.pow(1024, power)).toFixed(precision) + units[power];
}

console.log('10240 = ' + (10240).prefix()) // 10.00K
console.log('1234000 = ' + (1234000).prefix(1)) // 1.2M
console.log('10000 = ' + (-10000).prefix()) // -9.77K


(11000) .prefix () équivaut à 10,74K pas très précis devrait dire 11,00K
bmaggi

1
@bmaggi Il suffit de changer le 1024 en 1000
Steely Wing

1

Amélioration de la réponse de @ tfmontague pour formater les décimales. 33,0k à 33k

largeNumberFormatter(value: number): any {
   let result: any = value;

   if (value >= 1e3 && value < 1e6) { result = (value / 1e3).toFixed(1).replace(/\.0$/, '') + 'K'; }
   if (value >= 1e6 && value < 1e9) { result = (value / 1e6).toFixed(1).replace(/\.0$/, '') + 'M'; }
   if (value >= 1e9) { result = (value / 1e9).toFixed(1).replace(/\.0$/, '') + 'T'; }

   return result;
}

1

Je ne suis satisfait d'aucune des solutions publiées, voici donc ma version:

  1. Prend en charge les nombres positifs et négatifs
  2. Prend en charge les exposants négatifs
  3. Arrondit au prochain exposant si possible
  4. Effectue la vérification des limites (ne génère pas d'erreur pour les très grands / petits nombres)
  5. Supprime les zéros / espaces de fin
  6. Prend en charge un paramètre de précision

    function abbreviateNumber(number,digits=2) {
      var expK = Math.floor(Math.log10(Math.abs(number)) / 3);
      var scaled = number / Math.pow(1000, expK);
    
      if(Math.abs(scaled.toFixed(digits))>=1000) { // Check for rounding to next exponent
        scaled /= 1000;
        expK += 1;
      }
    
      var SI_SYMBOLS = "apμm kMGTPE";
      var BASE0_OFFSET = SI_SYMBOLS.indexOf(' ');
    
      if (expK + BASE0_OFFSET>=SI_SYMBOLS.length) { // Bound check
        expK = SI_SYMBOLS.length-1 - BASE0_OFFSET;
        scaled = number / Math.pow(1000, expK);
      }
      else if (expK + BASE0_OFFSET < 0) return 0;  // Too small
    
      return scaled.toFixed(digits).replace(/(\.|(\..*?))0+$/,'$2') + SI_SYMBOLS[expK+BASE0_OFFSET].trim();
    }
    
    //////////////////
    
    const tests = [
      [0.0000000000001,2],
      [0.00000000001,2],
      [0.000000001,2],
      [0.000001,2],
      [0.001,2],
      [0.0016,2],
      [-0.0016,2],
      [0.01,2],
      [1,2],
      [999.99,2],
      [999.99,1],
      [-999.99,1],
      [999999,2],
      [999999999999,2],
      [999999999999999999,2],
      [99999999999999999999,2],
    ];
    
    for (var i = 0; i < tests.length; i++) {
      console.log(abbreviateNumber(tests[i][0], tests[i][1]) );
    }


1

J'en ai trouvé un très codé au golf, et il est très court!

var beautify=n=>((Math.log10(n)/3|0)==0)?n:Number((n/Math.pow(10,(Math.log10(n)/3|0)*3)).toFixed(1))+["","K","M","B","T",][Math.log10(n)/3|0];

console.log(beautify(1000))
console.log(beautify(10000000))


1

Amélioration de la réponse de Salman grâce aux cas comme nFormatter (999999,1) qui renvoie 1000K.

function formatNumberWithMetricPrefix(num, digits = 1) {
  const si = [
    {value: 1e18, symbol: 'E'},
    {value: 1e15, symbol: 'P'},
    {value: 1e12, symbol: 'T'},
    {value: 1e9, symbol: 'G'},
    {value: 1e6, symbol: 'M'},
    {value: 1e3, symbol: 'k'},
    {value: 0, symbol: ''},
  ];
  const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
  function divideNum(divider) {
    return (num / (divider || 1)).toFixed(digits);
  }

  let i = si.findIndex(({value}) => num >= value);
  if (+divideNum(si[i].value) >= 1e3 && si[i - 1]) {
    i -= 1;
  }
  const {value, symbol} = si[i];
  return divideNum(value).replace(rx, '$1') + symbol;
}

1

Le moyen le plus simple et le plus simple de procéder est

new Intl.NumberFormat('en-IN', { 
    notation: "compact",
    compactDisplay: "short",
    style: 'currency',
    currency: 'INR'
}).format(1000).replace("T", "K")

Cela fonctionne pour n'importe quel nombre. Y compris L Cretc.


1

En éliminant la boucle dans la solution @ martin-sznapka, vous réduirez le temps d'exécution de 40%.

function formatNum(num,digits) {
    let units = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
    let floor = Math.floor(Math.abs(num).toString().length / 3);
    let value=+(num / Math.pow(1000, floor))
    return value.toFixed(value > 1?digits:2) + units[floor - 1];

}

Test de vitesse (200000 échantillons aléatoires) pour une solution différente de ce fil

Execution time: formatNum          418  ms
Execution time: kFormatter         438  ms it just use "k" no "M".."T" 
Execution time: beautify           593  ms doesnt support - negatives
Execution time: shortenLargeNumber 682  ms    
Execution time: Intl.NumberFormat  13197ms 

0
/*including negative values*/    
function nFormatter(num) {
      let neg = false;
       if(num < 0){
         num = num * -1;
         neg = true;
       }
       if (num >= 1000000000) {
         if(neg){
           return -1 * (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';  
         }
         return (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'G';
       }
       if (num >= 1000000) {
         if(neg){
           return -1 * (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';  
         }
         return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
       }
       if (num >= 1000) {
         if(neg){
           return -1 * (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';  
         }
         return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
       }
       return num;
    }

pls ajouter une explication de votre solution
Harun Diluka Heshan

0

Cette fonction peut transformer des nombres énormes (positifs et négatifs) en un format convivial pour les lecteurs sans perdre sa précision:

function abbrNum(n) {
    if (!n || (n && typeof n !== 'number')) {
      return '';
    }

    const ranges = [
      { divider: 1e12 , suffix: 't' },
      { divider: 1e9 , suffix: 'b' },
      { divider: 1e6 , suffix: 'm' },
      { divider: 1e3 , suffix: 'k' }
    ];
    const range = ranges.find(r => Math.abs(n) >= r.divider);
    if (range) {
      return (n / range.divider).toString() + range.suffix;
    }
    return n.toString();
}

/* test cases */
let testAry = [99, 1200, -150000, 9000000];
let resultAry = testAry.map(abbrNum);
console.log("result array: " + resultAry);


0

J'utilise cette fonction. Cela fonctionne pour les deux phpet javascript.

    /**
     * @param $n
     * @return string
     * Use to convert large positive numbers in to short form like 1K+, 100K+, 199K+, 1M+, 10M+, 1B+ etc
     */
 function num_format($n) {
        $n_format = null;
        $suffix = null;
        if ($n > 0 && $n < 1000) {
           $n_format = Math.floor($n);   
            $suffix = '';
        }
        else if ($n == 1000) {
            $n_format = Math.floor($n / 1000);   //For PHP only use floor function insted of Math.floor()
            $suffix = 'K';
        }
        else if ($n > 1000 && $n < 1000000) {
            $n_format = Math.floor($n / 1000);
            $suffix = 'K+';
        } else if ($n == 1000000) {
            $n_format = Math.floor($n / 1000000);
            $suffix = 'M';
        } else if ($n > 1000000 && $n < 1000000000) {
            $n_format = Math.floor($n / 1000000);
            $suffix = 'M+';
        } else if ($n == 1000000000) {
            $n_format = Math.floor($n / 1000000000);
            $suffix = 'B';
        } else if ($n > 1000000000 && $n < 1000000000000) {
            $n_format = Math.floor($n / 1000000000);
            $suffix = 'B+';
        } else if ($n == 1000000000000) {
            $n_format = Math.floor($n / 1000000000000);
            $suffix = 'T';
        } else if ($n >= 1000000000000) {
            $n_format = Math.floor($n / 1000000000000);
            $suffix = 'T+';
        }


       /***** For PHP  ******/
       //  return !empty($n_format . $suffix) ? $n_format . $suffix : 0;

       /***** For Javascript ******/
        return ($n_format + $suffix).length > 0 ? $n_format + $suffix : 0;
    }

0

J'ai décidé de développer beaucoup la réponse de @ Novellizator ici pour répondre à mes besoins. Je voulais une fonction flexible pour gérer la plupart de mes besoins de formatage sans bibliothèques externes.

Caractéristiques

  • Option pour utiliser les suffixes de commande (k, M, etc.)
    • Option pour spécifier une liste personnalisée de suffixes de commande à utiliser
    • Option pour contraindre l'ordre minimum et maximum
  • Contrôle du nombre de décimales
  • Virgules de séparation automatique de l'ordre
  • Formatage en pourcentage ou en dollars facultatif
  • Contrôle de ce qu'il faut renvoyer en cas de saisie non numérique
  • Fonctionne sur les nombres négatifs et infinis

Exemples

let x = 1234567.8;
formatNumber(x);  // '1,234,568'
formatNumber(x, {useOrderSuffix: true});  // '1M'
formatNumber(x, {useOrderSuffix: true, decimals: 3, maxOrder: 1});  // '1,234.568k'
formatNumber(x, {decimals: 2, style: '$'});  // '$1,234,567.80'

x = 10.615;
formatNumber(x, {style: '%'});  // '1,062%'
formatNumber(x, {useOrderSuffix: true, decimals: 1, style: '%'});  // '1.1k%'
formatNumber(x, {useOrderSuffix: true, decimals: 5, style: '%', minOrder: 2});  // '0.00106M%'

formatNumber(-Infinity);  // '-∞'
formatNumber(NaN);  // ''
formatNumber(NaN, {valueIfNaN: NaN});  // NaN

Fonction

/*
 * Return the given number as a formatted string.  The default format is a plain
 * integer with thousands-separator commas.  The optional parameters facilitate
 * other formats:
 *   - decimals = the number of decimals places to round to and show
 *   - valueIfNaN = the value to show for non-numeric input
 *   - style
 *     - '%': multiplies by 100 and appends a percent symbol
 *     - '$': prepends a dollar sign
 *   - useOrderSuffix = whether to use suffixes like k for 1,000, etc.
 *   - orderSuffixes = the list of suffixes to use
 *   - minOrder and maxOrder allow the order to be constrained.  Examples:
 *     - minOrder = 1 means the k suffix should be used for numbers < 1,000
 *     - maxOrder = 1 means the k suffix should be used for numbers >= 1,000,000
 */
function formatNumber(number, {
    decimals = 0,
    valueIfNaN = '',
    style = '',
    useOrderSuffix = false,
    orderSuffixes = ['', 'k', 'M', 'B', 'T'],
    minOrder = 0,
    maxOrder = Infinity
  } = {}) {

  let x = parseFloat(number);

  if (isNaN(x))
    return valueIfNaN;

  if (style === '%')
    x *= 100.0;

  let order;
  if (!isFinite(x) || !useOrderSuffix)
    order = 0;
  else if (minOrder === maxOrder)
    order = minOrder;
  else {
    const unboundedOrder = Math.floor(Math.log10(Math.abs(x)) / 3);
    order = Math.max(
      0,
      minOrder,
      Math.min(unboundedOrder, maxOrder, orderSuffixes.length - 1)
    );
  }

  const orderSuffix = orderSuffixes[order];
  if (order !== 0)
    x /= Math.pow(10, order * 3);

  return (style === '$' ? '$' : '') +
    x.toLocaleString(
      'en-US',
      {
        style: 'decimal',
        minimumFractionDigits: decimals,
        maximumFractionDigits: decimals
      }
    ) +
    orderSuffix +
    (style === '%' ? '%' : '');
}

0

Wow, il y a tellement de réponses ici. Je pensais que je pourrais vous expliquer comment je l'ai résolu car il semblait être le plus facile à lire, gère les nombres négatifs et va loin dans la plage de nombres kilos pour JavaScript. Il serait également facile de changer ce que vous voulez ou d'étendre encore plus loin.

const symbols = [
  { value: 1, symbol: '' },
  { value: 1e3, symbol: 'k' },
  { value: 1e6, symbol: 'M' },
  { value: 1e9, symbol: 'G' },
  { value: 1e12, symbol: 'T' },
  { value: 1e15, symbol: 'P' },
  { value: 1e18, symbol: 'E' }
];

function numberFormatter(num, digits) {
  const numToCheck = Math.abs(num);
  for (let i = symbols.length - 1; i >= 0; i--) {
    if (numToCheck >= symbols[i].value) {
      const newNumber = (num / symbols[i].value).toFixed(digits);
      return `${newNumber}${symbols[i].symbol}`;
    }
  }
  return '0';
}

const tests = [
  { num: 1234, digits: 1 },
  { num: 100000000, digits: 1 },
  { num: 299792458, digits: 1 },
  { num: 759878, digits: 1 },
  { num: -759878, digits: 0 },
  { num: 123, digits: 1 },
  { num: 123.456, digits: 1 },
  { num: -123.456, digits: 2 },
  { num: 123.456, digits: 4 }
];
for (let i = 0; i < tests.length; i++) {
  console.log(`numberFormatter(${tests[i].num}, ${tests[i].digits})=${numberFormatter(tests[i].num, tests[i].digits)}`);
}


0

Une alternative plus courte:

function nFormatter(num) {
    const format = [
      { value: 1e18, symbol: 'E' },
      { value: 1e15, symbol: 'P' },
      { value: 1e12, symbol: 'T' },
      { value: 1e9, symbol: 'G' },
      { value: 1e6, symbol: 'M' },
      { value: 1e3, symbol: 'k' },
      { value: 1, symbol: '' },
    ];
    const formatIndex = format.findIndex((data) => num >= data.value);
    console.log(formatIndex)
    return (num / format[formatIndex === -1? 6: formatIndex].value).toFixed(2) + format[formatIndex === -1?6: formatIndex].symbol;
  }
  

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.