こんにちは
配列だと splice() というメソッドが、そのような働きをしますが、文字列の spliceメソッドは無いです。なので、どうやって代替するのがよいか?ということになりますが、以下の投稿をみつけました。
上記の質問へのベストアンサー で挙げられている以下
javascript
1function spliceSlice(str, index, count, add) {
2 // We cannot pass negative indexes directly to the 2nd slicing operation.
3 if (index < 0) {
4 index = str.length + index;
5 if (index < 0) {
6 index = 0;
7 }
8 }
9
10 return str.slice(0, index) + (add || "") + str.slice(index + count);
11}
を使うか、もしくは頻繁に使うのであれば、上記の回答に対するコメント
You can add this globally with: String.prototype.splice = function (index, count, add) { return this.slice(0, index) + (add || "") + this.slice(index + count); } Just keep in mind it doesn't work exactly the same as the array splice method because strings are immutable (you can't modify them once created). So usage would be like: var s="ss"; s = s.splice(0,1,"t"); – William Neely Nov 18 '14 at 16:52
にあるように、
javascript
1String.prototype.splice = function (index, count, add) { return this.slice(0, index) + (add || "") + this.slice(index + count); }
とするのも一案として検討してよいかもしれません。
ただし、R.Mizukamiさんからコメントでご指摘がありましたように、 splice
をそのままメソッド名に使うのは若干憚られるため、仮に replaceSubsequence
としておき、以下、その使用例です。
以上、参考になれば幸いです。
追記1
Y.NINOMIYAさんのご質問の本文中に
そもそものそのような関数はないのでしょうか。最初は指定箇所以外を切り取って別で連結させる方法をとっっていたのですが非効率な気がし、やり方を調べていて今に至った形です。
とありましたが、上記に対する直接の回答としては、以下の二点です。
そのような関数はないのでしょうか。
答え: Stringの標準メソッドとして、そのものズバリのメソッドは用意されていないです。
最初は指定箇所以外を切り取って別で連結させる方法をとっっていたのですが非効率な気がし、
答え: 先述のstackoverflow のベストアンサーのコードも、そのような、「切り取って別で連結させる」ものですので、Y.NINOMIYAさんがご自身で書いた、一見「非効率な気が」するコードでよいのではと思いますが、それでもご自身のコードに確信が持てない場合は、そちらのコードを開示して、「このコードに非効率なところはありませんか?」というご質問をされると、より求めていらっしゃる回答が得られるかもしれません。
追記2
参考までに、先に挙げたstackoverflowのベストアンサー では、配列の splice
を経由する、以下の spliceSplit
javascript
1function spliceSplit(str, index, count, add) {
2 var ar = str.split('');
3 ar.splice(index, count, add);
4 return ar.join('');
5}
と比較して、 置き換え後の文字列をslice
で得られる前後の文字列で挟むように連結する(この回答の冒頭に挙げた) spliceSlice
のほうがパフォーマンスが良かったことを、以下のようにパフォーマンスツールでの実測へのリンクを挙げて説明しています。
Here's a jsperf that compares the two and a couple other methods.
追記3
文字列を操作するための vocajs というライブラリがあります。Githubのレポジトリに現時点で、約2700のStarがついているので、それなりに支持されているようですが、このライブラリでは、(先ほど "若干憚られる" と書いた) splice
という名前でご要望のメソッドが、以下のように提供されています。
v.splice(subjectopt='', start, deleteCountopt=subject.length-start, toAddopt='') → {string}
Changes subject by deleting deleteCount of characters starting at position start. Places a new string toAdd instead of deleted characters.
この Voca の spliceメソッドのソースコードを見てみると、以下
のように、やっていることは、先の spliceSlice
と基本的には同じでした。
追記4
質問への追記・修正、ベストアンサー選択の依頼へのY.NINOMIYAさんの以下のコメント
Y.NINOMIYA 2019/11/01 13:03
var str = "Hello,World!";
console.log(str);
var str_1 = str.substr(0, 6) //"Hello"を切り出し
var str_2 = str.substr(11, 1); //"!"を切り出し
str = str_1 + "Japan" + str_2;
console.log(str); //“Hello,Japan!”と出力
このような形でやっていました
を拝読したので、追記します。
- 文字列
var str = "Hello,World!"
に含まれる部分文字列 "World"
を "Japan"
に置き換えて、 "Hello,Japan!"
という文字列を得たい。
ということが課題であるとすると、この課題を解決するための手段として、ご質問にある
文字列の◯番目から△番目を他の文字列に置換
するという方法を選ぶこと自体が非効率かもしれません。(この場合の「非効率」とは「わざわざ面倒なやり方をしている」ぐらいの意味です。)
なぜなら
javascript
1var str_1 = str.substr(0, 6);
2var str_2 = str.substr(11, 1);
というコードを書こうとすると、6
や 11
という数を得るために World
の直前と直後のインデクスを目視で数えなければならないからです。そのようなことをしなくても、 var str = "Hello,World!"
に含まれる"World"
を "Japan"
に置き換えるには、 replaceを使って、以下で済みます。
javascript
1var str = "Hello,World!";
2
3str = str.replace('World', 'Japan');
4
5console.log(str);
Y.NINOMIYAさんとしては
文字列の◯番目から△番目を他の文字列に置換
するというやり方にこだわりがおありで、文字列に対して、 Array のsplice のような操作をするときの効率的なやり方をお求めなのか、または、 "World"
を "Japan"
に置き換えることが主目的なので、
文字列の◯番目から△番目を他の文字列に置換
するという方針も見直せる余地がおありなのかは、回答者には分からないところはありますが、"World"
を "Japan"
に置き換えたい、ということであれば、 6
や 11
を使わなくて済む
str.replace('World', 'Japan')
をお勧めしたいと思います。
追記5
質問への追記・修正、ベストアンサー選択の依頼へのコメントに、Y.NINOMIYAさんからのコメントで
Y.NINOMIYA 2019/11/01 22:18
置き換えたい文字列が全体に複数ある場合に対応するため、また、全体の文字列もある程度規則性があり、置換の開始位置はそうそう変わらないので「文字列の◯番目から△番目を置換する」という方法を取りたかったのです。
とありましたので、これをふまえて元のご質問にある
そもそものそのような関数はないのでしょうか。最初は指定箇所以外を切り取って別で連結させる方法をとっっていたのですが非効率な気がし、やり方を調べていて今に至った形です。
に返答します。
非効率な気がし
とのことですが、「文字列の◯番目から△番目を置換する」方法として、Y.NINOMIYA さんがお書きになった
javascript
1var str = "Hello,World!";
2var str_1 = str.substr(0, 6) //"Hello"を切り出し
3var str_2 = str.substr(11, 1); //"!"を切り出し
4str = str_1 + "Japan" + str_2;
というコードが、アルゴリズムとして、特段、効率が悪いことをやっている、ということはないと思います。
ただ、
置き換えたい文字列が全体に複数ある場合に対応するため、また、全体の文字列もある程度規則性があり、置換の開始位置はそうそう変わらないので
とのことだったので、毎回、前方部分と後方部分を切り出して、置換後の文字列と連結するコードを書くのは煩わしい、ということはあると思うので、先に挙げた 、stackoverflow のベストアンサーに挙げられていた spliceSlice() のような関数を自作して使い回すか、あるいは自作も不要な策として、追記3で挙げた、vocajsのsplice を使ってみることを検討してみてもよいかもしれません。
以下は、vocajsのsplice を使って "Hello,World!"
の "World" を "Japan" に置き換える例です。