Luaの文字列は不変です。つまり、文字列内のテキストを置き換えるソリューションは、最終的に目的のコンテンツで新しい文字列を作成する必要があります。単一の文字を他のコンテンツに置き換える特定のケースでは、元の文字列をプレフィックス部分とポストフィックス部分に分割し、それらを新しいコンテンツの周りに連結して戻す必要があります。
コードのこのバリエーション:
function replace_char(pos, str, r)
return str:sub(1, pos-1) .. r .. str:sub(pos+1)
end
簡単なLuaへの最も直接的な翻訳です。ほとんどの目的にはおそらく十分に高速です。プレフィックスが最初のpos-1
文字である必要があるというバグを修正し、の最後の引数string.sub
が欠落している場合-1
、文字列の終わりと同等であると見なされるという事実を利用しました。
ただし、ガベージコレクションがそれらを食い尽くすまで文字列ストアでぶらぶらする一時的な文字列がいくつか作成されることに注意してください。プレフィックスとポストフィックスの一時的なものは、どのソリューションでも回避できません。ただし、これは、最初の..
オペレーターが2番目のオペレーターによって消費される一時的なものも作成する必要があります。
2つの代替アプローチのいずれかがより高速である可能性があります。1つ目は、PaŭloEbermannが提供するソリューションですが、わずかな調整が1つあります。
function replace_char2(pos, str, r)
return ("%s%s%s"):format(str:sub(1,pos-1), r, str:sub(pos+1))
end
これはstring.format
、余分な一時オブジェクトを必要とせずに最終的なバッファサイズを推測できることを期待して、結果のアセンブリを実行するために使用します。
ただし、フォーマットを通過する文字列の文字にstring.format
問題が発生する可能性があることに注意してください。具体的には、標準Cの関数で実装されているため、。の最初の出現時に置換された文字列を終了することを期待するのが妥当です。(コメントの中でユーザーの妄想論理によって指摘されています。)\0
%s
sprintf()
\0
頭に浮かぶ3番目の選択肢はこれです:
function replace_char3(pos, str, r)
return table.concat{str:sub(1,pos-1), r, str:sub(pos+1)}
end
table.concat
文字列のリストを効率的に連結して最終結果にします。これには、文字列の間に挿入するテキストであるオプションの2番目の引数があります。これは、デフォルトで、""
ここでの目的に適しています。
私の推測では、文字列が巨大で、この置換を頻繁に行わない限り、これらのメソッド間で実際のパフォーマンスの違いは見られません。ただし、以前は驚いたことがあるので、アプリケーションのプロファイルを作成してボトルネックがあることを確認し、潜在的なソリューションを慎重にベンチマークします。