Hatoblog(はとブログ)

JavaScriptでゼロパディングする(文字列を埋める)メソッド【padStart、padEnd】

昔は冗長な書き方でしか書けなかったゼロパディングが、ECMAScript 2017より登場した便利なメソッドによって、とても簡単に書けるようになりました。

以前、このようなツイートをしました。

今回はこの内容について、より詳しく解説していきます。

ゼロパディングとは、指定した長さになるように文字列を埋めることです。

例えば、最大5ケタの数字がランダムに入る場所の長さ(ケタ数)を固定にしたいとき、昔はこんな感じで書いていました。

// ランダムな数字を文字列化したもの
let num1 = "15";
let num2 = "4320";
let num3 = "77777";

// 5ケタに合わせる
// 一旦0を5ケタ分足して、後ろから5ケタを取得
console.log( ("00000" + num1).slice(-5) ); // 00015
console.log( ("00000" + num2).slice(-5) ); // 04320
console.log( ("00000" + num3).slice(-5) ); // 77777

このように、とりあえず先頭に0を足して後ろから5ケタを取得する、という書き方が一般的でした。当時の書き方では一番スマートだと思います。

ですが、この関数が登場してからはもっと無駄なく書くことが出来ます。

// ランダムな数字を文字列化したもの
let num1 = "15";
let num2 = "4320";
let num3 = "77777";

// 5ケタに合わせる
// padStartを使う
console.log( num1.padStart(5, 0) ); // 00015
console.log( num2.padStart(5, 0) ); // 04320
console.log( num3.padStart(5, 0) ); // 77777

記述量も少し減りますし、何より一旦0を足すなどの無駄な動きがありません。後ほど詳しく解説しますが、ゼロパディングをしたいときは今後このメソッド一択になると思うので、記憶の片隅に置いておいて損はありません。

ただ、比較的新しく定義されたメソッドなため、IE11では当然のように非対応です。しかし、後で説明するポリフィルを使うことで、IE11以前でも使えますのでご安心ください。

目次

各メソッドの概要

padStart

padStart() メソッドは、結果の文字列が指定した長さになるように、現在の文字列を他の文字列で (必要に応じて繰り返して) 延長します。延長は、現在の文字列の先頭から適用されます。

String.prototype.padStart()

padEnd

padEnd() メソッドは、最終的な文字列が指定された長さに到達するように、現在の文字列を指定した文字列で(繰り返し)延長します。延長は、現在の文字列の終端(右)から適用されます。

String.prototype.padEnd()

この2つは似ていますが、padStartは左側(文字列のStart側)、padEndは右側(文字列のEnd側)を指定文字で埋めていくという違いがあります。

ですので、上で書いた0で埋めていく例は、左側に0を入れていきたかったので、padStartの方を使ったというわけになります。

padStart、padEndの使い方

基本的な動作について解説します。下記の構文の通りです。

//padStart
str.padStart( targetLength [, padString] );

// padEnd
str.padEnd( targetLength [, padString] );

str
対象とする文字列です。この文字列をベースに、指定した文字列で埋めていきます。

targetLength
最終的な文字列の長さを設定します。例えばここが5であれば、最終的な文字列は5文字(数字なら5ケタ)になります。

padString
ベースの文字列を埋める文字列です。
オプションになっており、指定しなくても動きます。その時の穴埋めの文字は” “(半角スペース)です。

実際の使い方は以下のようになります。

// padStart
// 第2引数を省略した場合は半角スペースで埋める
"abc".padStart( 10 ); // "       abc"
// 3ケタになるまで0で埋める
"5".padStart( 3, "0" ); // "005"
// ベースの文字列の方が長かったらそのまま返ってくる
"abcdefg".padStart( 3, "z" ); // "abcdefg"
// 最終的な文字列長さよりも埋める文字列の方が長かったら、途中で切れる
"9".padStart( 5, "01234567" ); // "01239"

// padEnd
// 基本はpadStartと同じだが、右から埋める
"abc".padEnd( 10 ); // "abc       "
"abc".padEnd( 10, "foo" );  // "abcfoofoof"

IE11で使いたいときはポリフィルを使おう

ポリフィルとは、今回のIE11のように対応していないブラウザ等に対応させるために、同じ関数の動きを同じ名前で作り、それを使う方法です。

今回のpadStart、padEndの場合は下記のコードを先に読み込んでおくことで、対応しているブラウザの時と同じように使うことが出来るようになります。

// padStart
if (!String.prototype.padStart) {
  String.prototype.padStart = function padStart(targetLength, padString) {
    targetLength = targetLength >> 0; //truncate if number, or convert non-number to 0;
    padString = String(typeof padString !== 'undefined' ? padString : ' ');
    if (this.length >= targetLength) {
      return String(this);
    } else {
      targetLength = targetLength - this.length;
    if (targetLength > padString.length) {
      padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
    }
    return padString.slice(0, targetLength) + String(this);
    }
  };
}

// padEnd
if (!String.prototype.padEnd) {
  String.prototype.padEnd = function padEnd(targetLength,padString) {
    targetLength = targetLength>>0; //floor if number or convert non-number to 0;
    padString = String((typeof padString !== 'undefined' ? padString : ' '));
    if (this.length > targetLength) {
      return String(this);
    } else {
      targetLength = targetLength-this.length;
      if (targetLength > padString.length) {
        padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
      }
      return String(this) + padString.slice(0,targetLength);
    }
  };
}

もしくは、babelなどのトランスパイラというものを使って対応させるという手法もあり、慣れてくるとこちらをよく使ったりもしますが、初心者の方はとりあえずそういうものもあるという事を覚えておければいいのかなと思います。

まとめ

今回はゼロパディングに最適なメソッドを紹介しました。

よく使うメソッドかどうかはまあ微妙なラインですが、覚えておけば便利なメソッドなので、ここぞという時に使ってみてください(?)