整数値3桁カンマ区切り、小数点部3桁スペース区切りにする関数

数値を3桁カンマ区切りにしたかったので行ってみました。

> 整数:123456789 >> 文字列:'123,456,789'
> 整数:1234567890 >> 文字列:'1,234,567,890'
> 小数:123.123456789 >> 文字列:'123.123 456 789'

整数だけがとりあえず作りたかったのですが、ついでだったので、小数点以下も区切れるようにしました。

JavaScriptは、整数と小数点とが同じ型な、なぞ言語なのでね。


小数点以下を、0に近いほうから区切るのが数学的な記述方法かどうかはしりませんが、とりあえずそのように実装しています。

# 環境

chrome / node.js / WSH
で、動くようにした。
テストもライブラリに含んでます。


# 関数の構造

・文字列を前方から指定数で区切る関数

・文字列を後方から指定数で区切る関数

を作っていて、

・数値をカンマ区切りにする関数

このメイン処理の内部で、数値を文字列変換した後、ピリオドで分解して前後を処理しているので、小数点以下の区切りを改良したかったら、正規表現を使ったものよりかは改良しやすいと思う。

とりあえず、3桁には限定せず桁数は指定できるし、区切り文字も指定できるようにしている。


ただ、コピペするにはライブラリの内部コードがたくさんありすぎるのでコピペ量は増えてしまうかもね。

# コード

もはや、素のJavaScriptに見えないが...
ライブラリから、切り出すのもめんどくさいから、すまん。
コピペしたい人は、たくさん切り取ってくれ。

```JavaScript

      //----------------------------------------
      //・数値を3桁カンマ区切りなどにする
      //----------------------------------------
      //  ・整数部分は右から
      //    小数部分は左から桁区切りする
      //----------------------------------------
      _.formatDigitComma = function (value,
        delimiterInt, digitInt, delimiterFloat, digitFloat) {
        var d = lib.debug;
        var t = lib.type;
        d.assert(t.isNumber(value));
        d.assert(t.isInt(digitInt));
        d.assert(t.isString(delimiterInt));
        d.assert(t.isInt(digitFloat));
        d.assert(t.isString(delimiterFloat));

        var s = lib.string;
        var valueStr = value.toString();
        if (t.isInt(value)) {
          return s.formatInsertLast(valueStr, delimiterInt, digitInt);
        } else {
          return s.formatInsertLast(
              s.startFirstDelim(valueStr, '.'),
              delimiterInt, digitInt) +
            '.' + 
            s.formatInsertFirst(
              s.endFirstDelim(valueStr, '.'),
              delimiterFloat, digitFloat);
        }
      };

      //----------------------------------------
      //・先頭から区切る
      //----------------------------------------
      _.formatInsertFirst = function (str, delimiter, count) {
        var t = lib.type;
        var d = lib.debug;
        d.assert(t.isString(str));
        d.assert(t.isString(delimiter));
        d.assert(t.isInt(count));
        var s = lib.string;
        if (s.isEmpty(str)) {
          return '';
        }

        //WSHは文字列をstr[i]の形で扱えないので
        //その対策を行う
        str = str.split('');

        var result = str[0];
        for (var i = 1; i <= str.length - 1; i += 1) {
          if (i % count === 0) {
            result += delimiter + str[i];
          } else {
            result += str[i];
          }
        }
        return result;
      };

      //----------------------------------------
      //・後方から区切る
      //----------------------------------------
      _.formatInsertLast = function (str, delimiter, count) {
        var t = lib.type;
        var d = lib.debug;
        d.assert(t.isString(str));
        d.assert(t.isString(delimiter));
        d.assert(t.isInt(count));
        var s = lib.string;
        if (s.isEmpty(str)) {
          return '';
        }

        //WSHは文字列をstr[i]の形で扱えないので
        //その対策を行う
        str = str.split('');

        var result = str[str.length - 1];
        for (var i = 1; i <= str.length - 1; i += 1) {
          if (i % count === 0) {
            result += delimiter + str[str.length - 1 - i];
          } else {
            result += str[str.length - 1 - i];
          }
        }
        return s.reverse(result);
      };

```
# 全体

GitHubで公開しています。
関数の依存関係はすごいと思いますが、実用関数はたくさんあるので、MITライセンスでご自由にどうぞ。

stsLib.js/stslib_core.js at master · standard-software/stsLib.js
https://github.com/standard-software/stsLib.js/blob/master/Source/stsLib.js/stslib_core.js
ver 2017/07/13 で今回の実装が含まれています。
後日変更になってたら、ver 2017/07/13 を見てください。


# 参考

[「金額とか、カンマ区切りの数値をJSで。」のつづき。小数点も考えてみたんだけどね...。 - Qiita](http://qiita.com/ariyo13/items/ec74de3cd721a68767fc#_reference-92ab1a1fa61991f65e9a)

参考にしました。

# あとがき

正規表現より、普通の実装が楽でいいわ。