【JavaScript】文字列のn番目の出現箇所を削除・置換するポリフィルの作成方法
今回は、文字列からn番目に出現する部分文字列を削除(置換)できるポリフィル関数 removeStr() を作成してみましょう。この関数は、以下の引数を受け取ります。
- subStr … 削除対象となる部分文字列
- num … 何番目の出現箇所を削除するかを指定する数値
この関数は、部分文字列の削除に成功すれば新しい文字列を返し、失敗した場合はすべてのケースで -1 を返す仕様です。
たとえば、次のような呼び出しを行います。
const str = 'drsfgdrrtdr';
console.log(str.removeStr('dr', 3));
この場合の期待される出力は以下のとおりです。
'drsfgdrrt'
それでは、実際にコードを書いていきましょう。
コード例
const str = 'drsfgdrrtdr';
const subStr = 'dr';
const num = 2;
removeStr = function(subStr, num){
if(!this.includes(subStr)){
return -1;
}
let start = 0, end = subStr.length;
let occurences = 0;
for(; ;end < this.length){
if(this.substring(start, end) === subStr){
occurences++;
};
if(occurences === num){
return this.substring(0, start) + this.substring(
end, this.length);
};
end++;
start++;
}
return -1;
}
String.prototype.removeStr = removeStr;
console.log(str.removeStr(subStr, num));
出力結果
このコードをコンソールで実行すると、次のように表示されます。
drsfgrtdr
コードの解説
removeStr()関数は、まずsubStrが文字列内に一度も出現しない場合に備えて、その時点で-1を返して処理を終了します。次に、スライディングウィンドウ(尺取り)アルゴリズムを使って、文字列中における
subStrの出現回数を数えていきます。ここでウィンドウのサイズは、部分文字列の長さと同一になります。処理は最も左側のウィンドウから開始し、ウィンドウの終端が元の文字列の末尾に到達するまで順番にスライドさせていきます。
走査の途中で出現カウントが指定された番号(
num)と一致したら、その該当箇所を文字列から切り取り、結合した新しい文字列を返します。文字列全体を最後まで走査しても条件が満たされなければ、
subStrが必要な回数だけ存在しないことになるため、-1を返して関数を終了します。
最後に、removeStr を String.prototype に登録することで、組み込みメソッドと同じように、任意の文字列から直接呼び出せるようになります。
なお、ネイティブプロトタイプを拡張する際は、既存コードとの名前衝突に注意し、実務では Object.defineProperty() で列挙不可にするなどの配慮を行うと安全です。
-
JavaScriptで文字列を圧縮する方法|ランレングス圧縮の実装
本記事では、連続して繰り返される文字を含む可能性のある文字列を受け取り、それを圧縮して返すJavaScript関数の実装方法を解説します。 文字列圧縮のルール この関数は、連続する同じ文字を「1文字+連続回数」の形式に変換することで、文字列を圧縮します。 k4j 圧縮しても短くならない場合の扱い ただし、圧縮後の文字列の長さが元の文字列以上になってしまう場合は、圧縮を行わずに元の文字列をそのまま返す必要があります。 たとえば「aab」は「a2b1」と圧縮できますが、長さが3文字から4文字に増えてしまいます。このようなケースでは、関数は元の「aab」を返すように設計します。 サンプルコード 実
-
Pythonで文字列内の重複する出現箇所だけを置換する方法
文字列の中に同じ単語が何度も現れる場合、1回目の出現はそのまま残し、2回目以降の重複箇所だけを別の言葉に置き換えたいというケースがあります。Pythonでは、辞書のキー、「index」メソッド、そしてリスト内包表記を組み合わせることで、この処理をシンプルに実現できます。 リスト内包表記は、リストを反復処理しながら各要素に操作を加えるための簡潔な記法です。また、「index」メソッドは、指定した値がリスト内で最初に出現する位置(インデックス)を返します。この性質を利用することで、現在処理中の位置が最初の出現位置と一致するかどうかを判定できます。 以下に具体的な実装例を示します。 サンプルコード