import std.stdio; import std.algorithm; import std.range; import std.string; char f(char x) { if ( x >= '0' && x <= '9' ) return '9' - x + '0'; if ( x >= 'A' && x <= 'Z' ) return x - 'A' + 'a'; return x; } template toArray(R) if (isInputRange!(R)) { auto toArray(R r) { ElementType!(R)[] res; foreach (e; r) res ~= e; return res; } } void main() { string str = "Abc012_59F_#012Gh"; writeln(str); string[] ss = split(str, "#"); auto res = toArray(map!(f)(ss[0])) ~ "#" ~ ss[1]; writeln(res); }
うーん?
- import文が多い
- fがin-placeに書けない(delegateリテラルがmapのテンプレート引数に書けない)
- mapの結果であるRangeオブジェクトを組み込み配列に自分で変換しなければ"#"以降の文字列と連結できない
- chainを使うと結果がおかしくなった(文字列なのに数字の列になった).
元のC++コードのようにiteratorベースのコードにした方がスマートに書けるだろうか?
std.iteratorってのがあったはずだけど何ができたっけなぁ.
こんなこといいな できたらいいな
import std.stdio; import std.algorithm; import std.range; void main() { auto res = map!("a * a")(cast(int[])[1,2,3]); writeln(res); } // Rangeオブジェクトの型が表示できなくなるけど標準にあったらいいな template writeln(R) if (isInputRange!(R)) { void writeln(R r) { foreach (e; r) std.stdio.write(e); std.stdio.writeln(); } }
でしょ?
(追記:このままじゃダメみたいだ)