AからZまでの26文字を含む文字列を生成する §
AからZまでの26文字を含む文字列が欲しいとします。
しかし、var atoz1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";のようなコードは書きたくないとします。こういうことをすると間違いが入りやすいからです。
どうすれば良いのでしょうか?
C#の文字コードはUnicodeです。Unicodeの文字番号はAからZまで全て昇順で並んでいます。ですから、'A'の番号から1ずつ26回足していけば欲しい文字は全て揃います。
それらの文字を1つ1つ足していけば必要な文字列が得られます。
しかし、サンプルソースの【まわりくどい】例のようにforループをまわしていたらソースは無駄に長くなってしまいます。
そこでLINQを使って、Rangeメソッドで26個の数字を生成させています。それを更に加工して文字列に直せば目的達成です。
注意点は、数字(int)を文字(char)に直すことです。intのままだと数値扱いです。 サンプルソースのNGパターンのように文字ではなく文字の番号が出てしまいます。
罠の数々 §
- Select(c=>(char)c)の代わりにCast<char>()と書くことはできない。Castメソッドは全てを型をキャストできるわけではない。
参考リンク §
Enumerable.Range(Int32, Int32) メソッド
String.Concat メソッド
Enumerable.Select メソッド
なぜint型からchar型への変換が必要なのだろうか。最初からchar型でカウントすれば良いのではないだろうか。上記リンクからRangeの定義を確認し、変換が必要とされる理由を考えてみよう。
リポジトリ §
https://github.com/autumn009/cshowto
AtoZ §
using System;
using System.Linq;
using System.Text;
class Program
{
static void Main()
{
// こうは書きたくない
var atoz1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Console.WriteLine(atoz1);
// まわりくどい
var sb = new StringBuilder();
for (int i = 0; i < 26; i++)
{
sb.Append((char)(i + 'A'));
}
var atoz2 = sb.ToString();
Console.WriteLine(atoz2);
// LINQ使用
var atoz3 = string.Concat(Enumerable.Range('A', 26).Select(c => (char)c));
Console.WriteLine(atoz3);
// NG
var ng = string.Concat(Enumerable.Range('A', 26));
Console.WriteLine(ng);
}
}
実行結果
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
6566676869707172737475767778798081828384858687888990