LINQを使って、文字列における特定文字の出現回数をカウントする方法を解説する。LINQを使うと、何をしたいのかを簡潔に記述できる。
対象:.NET 3.5以降
指定された文字列中に、特定の文字が何回出現するかをカウントしたい場合、LINQを使って明瞭かつ簡潔に記述できる。本稿ではその方法を説明する。
以前の.NET TIPSで紹介したように、Stringクラス(System名前空間)のReplaceメソッドとLengthプロパティを組み合わせて、次のコードのように記述できる。
using System;
class Program
{
// 文字の出現回数をカウント
public static int CountChar(string s, char c)
{
return s.Length - s.Replace(c.ToString(), "").Length;
}
static void Main()
{
string s = "この文字列の中の「の」の数は?";
Console.WriteLine(CountChar(s, 'の')); // 出力:5
#if DEBUG
Console.ReadKey();
#endif
}
}
Module Module1
' 文字の出現回数をカウント
Public Function CountChar(ByVal s As String, ByVal c As Char) As Integer
Return s.Length - s.Replace(c.ToString(), "").Length
End Function
Sub Main()
Dim s As String = "この文字列の中の「の」の数は?"
Console.WriteLine(CountChar(s, CChar("の"))) ' 出力:5
#If DEBUG Then
Console.ReadKey()
#End If
End Sub
End Module
StringクラスのReplaceメソッドもLengthプロパティも効率よく動作するので、このコードで性能上は申し分ない。しかし、ReplaceメソッドとLengthプロパティを組み合わせたコードは、何をしているのか把握しづらい。そこで、この例ではメソッドに切り出し、「CountChar」というメソッド名を付けることで、コードの意図を明確にしている。
Stringクラスは、IEnumerable<char>/IEnumerable(Of Char)インターフェースを実装している(.NET Framework 3.5から)。従って、文字列から1文字ずつ取り出して行う処理には、System.Linq名前空間のEnumerableクラスにある拡張メソッドが利用できる。
特定文字の出現回数をカウントするには、EnumerableクラスのWhere拡張メソッドを使って特定の文字だけを取り出し*1、その数をEnumerableクラスのCount拡張メソッドを使ってカウントすればよい(次のコード)。
using System;
using System.Linq;
class Program
{
static void Main(string[] args)
{
string s = "この文字列の中の「の」の数は?";
Console.WriteLine(s.Where(c => c == >'の').Count()); // 出力:5
#if DEBUG
Console.ReadKey();
#endif
}
}
Module Module1
Sub Main()
Dim s As String = "この文字列の中の「の」の数は?"
Console.WriteLine(s.Where(Function(c) c = "の").Count()) ' 出力:5
#If DEBUG Then
Console.ReadKey()
#End If
End Sub
End Module
LINQを使った場合は、コードの意図が明確になる。この例のように、メソッドに切り出さず、コードの流れの中に記述してしまっても問題ないだろう。
なお、Count拡張メソッドには、カウントすべき対象をラムダ式で指定できるオーバーライドもある。それを使えば、さらに簡潔に記述できる(次のコード)。
// Console.WriteLine(s.Where(c => c == 'の').Count());
// 上の行は次のように書いてもよい
Console.WriteLine(s.Count(c => c == 'の'));
' Console.WriteLine(s.Where(Function(c) c = "の").Count())
' 上の行は次のように書いてもよい
Console.WriteLine(s.Count(Function(c) c = "の"))
以上のように、LINQを使うと特定文字の出現回数をカウントするコードが明瞭かつ簡潔に記述できる。ただし、StringクラスのReplaceメソッドを利用した処理の方が数倍ほど速いので、カウントする処理を繰り返す場合には注意してほしい。
*1 Where拡張メソッド/Count拡張メソッドの引数には、ラムダ式を与えている。ラムダ式について詳しくは、次のMSDNのドキュメントを参照していただきたい。
・MSDN:ラムダ式 (C# プログラミング ガイド)
・MSDN:ラムダ式(Visual Basic)
利用可能バージョン:.NET Framework 3.5以降
カテゴリ:クラスライブラリ 処理対象:LINQ
使用ライブラリ:Enumerableクラス(System.Linq名前空間)
関連TIPS:LINQ:数値コレクション内の特定の数値だけを集計するには?[C#、VB]
Copyright© Digital Advantage Corp. All Rights Reserved.