銀の弾丸

プログラミングに関して、いろいろ書き残していければと思っております。

npm「list-it」― コンソールへ列を揃えてデータを表示

コンソールへの表形式でのデータ表示を支援するNode.jsのモジュール(npm)「list-it」のご紹介。

2次元配列的なデータの列幅を揃えてキレイに表示。

文字列は左寄せ、数値は右寄せ。同じ列内の数値の小数点の位置も揃えます。

npmは、便利なツールが揃っていて、気楽にコードが書けるのがヨロシイですね。

f:id:takamints:20160501161451p:plain



駆け足でご説明するざっくりした使い方

  1. require("list-it")する。
  2. buffer()メソッドで空のバッファを作成。
  3. d()メソッドで、現在の行へ列(セル)データを追加。複数指定も可。
  4. nl()メソッドで現在行への列の追加を終了し次の行へ。
  5. 追加できるデータの型は文字列か数値。配列は行の追加になる(行追加時はnl()不要)
  6. 複数の配列を与えると複数の行が出来上がります。2次元配列でも可。
  7. toString()で文字列化してconsole.log()

機能の概要

表形式のデータを放り込んでコンソールへそのまま表示できる文字列を生成します。列ごとに数値の小数点位置を揃えられます。なんとなく便利でしょ?

  • autoAlign(自動整列)モードON(デフォルト)で、数値は小数点位置を揃えて右寄せ、文字列は普通に左寄せ。
  • 文字列の色や表示スタイルにANSIエスケープシーケンスが使用できます。カーソル移動とかは無理ですけどね。エスケープシーケンスのリセットは自動では行わないので、追加文字列の最後にリセットシーケンスを入れておいてください。

サンプルコードと出力例

japanese-foods.js

const ListIt = require("list-it");//①
const buf = new ListIt();      //②
console.log(
    buf
        .d("1").d("Sushi")      //③
            .d("vinegared rice combined raw seafood")
            .d("Healthy").nl()  //④
        .d("2").d("Yakiniku")
            .d("Grilled meat on Japanese")
            .d("Juicy").nl()
        .d("3").d("Ramen")
            .d("Japanese noodle soup dish")
            .d("I like it").nl()
        .d("4").d("Tempura")
            .d("Deep fried seafood or vegetables")
            .d("Delicious").nl()
        .d("5").d("Sashimi")
            .d("Very fresh sliced fish")
            .d("Try it now, It's good").nl()
        .toString());

出力: 文字列は左寄せです

$ node sample/japanese-food.js
1 Sushi    vinegared rice combined raw seafood Healthy
2 Yakiniku Grilled meat on Japanese            Juicy
3 Ramen    Japanese noodle soup dish           I like it
4 Tempura  Deep fried seafood or vegetables    Delicious
5 Sashimi  Very fresh sliced fish              Try it now, It's good

autoAlign

autoAlignオプションをtrueにすれば(デフォルトでtrueです)、データの型を考慮してセルの整形を行います。

planets.js

const ListIt = require("list-it");
const buf = new ListIt({ "autoAlign" : true });
var PLANETS = [
    ["NAME", "Mass(10^24kg)", "Dia(km)", "Dens(kg/m3)",
                        "Grav(m/s2)", "EscV(km/s)", "Rot(hours)" ],
    ["MERCURY", 0.33,   4879,   5427,   3.7,    4.3,    1407.6  ],
    ["VENUS",   4.87,   12104,  5243,   8.9,    10.4,   -5832.5 ],
    ["EARTH",   5.97,   12756,  5514,   9.8,    11.2,   23.9    ],
    ["MOON",    0.0073, 3475,   3340,   1.6,    2.4,    655.7   ],
    ["MARS",    0.642,  6792,   3933,   3.7,    5.0,    24.6    ],
    ["JUPITER", 1898,   142984, 1326,   23.1,   59.5,   9.9     ],
    ["SATURN",  568,    120536, 687,    9.0,    35.5,   10.7    ],
    ["URANUS",  86.8,   51118,  1271,   8.7,    21.3,   -17.2   ],
    ["NEPTUNE", 102,    49528,  1638,   11.0,   23.5,   16.1    ],
    ["PLUTO",   0.0146, 2370,   2095,   0.7,    1.3,    -153.3  ]
];
console.log( buf.d( PLANETS ).toString() ); //⑤、⑥

出力: 数値は小数点の位置を揃えて右寄せ

$ node sample/planets.js
NAME    Mass(10^24kg) Dia(km) Dens(kg/m3) Grav(m/s2) EscV(km/s) Rot(hours)
MERCURY        0.33      4879        5427        3.7        4.3     1407.6
VENUS          4.87     12104        5243        8.9       10.4    -5832.5
EARTH          5.97     12756        5514        9.8       11.2       23.9
MOON           0.0073    3475        3340        1.6        2.4      655.7
MARS           0.642     6792        3933        3.7        5.0       24.6
JUPITER     1898.0     142984        1326       23.1       59.5        9.9
SATURN       568.0     120536         687        9.0       35.5       10.7
URANUS        86.8      51118        1271        8.7       21.3      -17.2
NEPTUNE      102.0      49528        1638       11.0       23.5       16.1
PLUTO          0.0146    2370        2095        0.7        1.3     -153.3

日本語(ワイド文字)

japanese-foods-jp.js

const ListIt = require("list-it");
const buf = new ListIt();
console.log(
    buf
        .d("1").d("寿司")
            .d("酢とご飯とシーフード")
            .d("健康的だ").nl()
        .d("2").d("焼肉")
            .d("日本のグリルされたお肉")
            .d("ジューシー").nl()
        .d("3").d("ラーメン")
            .d("日本のスープに入った麺")
            .d("大好き").nl()
        .d("4").d("天ぷら")
            .d("シーフードや野菜に衣をつけて揚げたもの")
            .d("おいしー").nl()
        .d("5").d("刺身")
            .d("大変フレッシュな魚のスライス")
            .d("食べてみて!あご落ちるぜ").nl()
        .toString());

出力: HTMLでは何故か微妙にズレるけどコンソールではズレてません。

$ node sample/japanese-food-jp.js
1 寿司     酢とご飯とシーフード                   健康的だ
2 焼肉     日本のグリルされたお肉                 ジューシー
3 ラーメン 日本のスープに入った麺                 大好き
4 天ぷら   シーフードや野菜に衣をつけて揚げたもの おいしー
5 刺身     大変フレッシュな魚のスライス           食べてみて!あご落ちるぜ

未実装機能(将来追加する可能性はあり…ます…)

  • 文字列の折り返しができるようになればいいな。列幅指定してとか、コンソールの幅を判別して、自動的に列を折り返すとかできると超クール。
  • 見出し行とか見出しセルの概念を、我、欲す。行、列、セル単位でスタイル指定したい。
  • 表を転置(トランスポーズ:行列入れ替え)したいときがたまにある。
  • 演算機能があってもよいかなとか。あ、行列演算できてもよいか?いや、それはやりすぎか。

リポジトリ

メソッドの詳細などは、以下のリポジトリにあります。どう考えてもおかしな結果が得られたって時は、バンバンIssue入れてください。

GitHub

github.com

npm

www.npmjs.com

その他

これ、結構需要がある気がしていますが、プロジェクト単位でガチガチに力技で作ったりしがちですよね。 また、こういったモジュールは既にあるのかもしれませんが、軽く検索して見つけられなかったので作りました。

npmにはまる以前に作っていた別ソフトがベースになっています。 当時必要だと感じていた機能以上に、あれもこれもとドンドン実装したくなるから面白いもんですね。