100までの素数を求めるプログラム(3)

素数ネタは昨日の日記で終わる予定だったのですが,
http://d.hatena.ne.jp/akiramei/20060219
を読んでいるうちに,自分のコードのアホさ・センスの悪さに気付いたので再度リファクタリングします.

TrueForAllメソッド

昨日の日記ではIsPrimeメソッドを以下のようにリファクタリングしました.

static bool IsPrime(int target, List<int> primeList)
{
  return !primeList.Exists(delegate(int j) { return target % j == 0; } );
}

この,!primeList.Existsがいかにも不恰好です.

「primesに含まれる素数全てがiを割り切れない」の方が人間の思考に近い気がします……

あるリストの中に,ある条件に含まれる要素が存在するかを調べるもの(=メソッド)
はExistsメソッドですが,
あるリストの中の全ての要素が,ある条件を満たすかを調べるもの(=メソッド)
として,TrueForAllメソッドが用意されています(……っていうか,最初にakirameiさんがコメントしてるじゃん!ダメだ>オレ).
そんなわけで,さらにTrueForAllでリファクタリング

static bool IsPrime(int target, List<int> primeList)
{
  return primeList.TrueForAll(delegate(int j) { return target % j != 0; } );
}

GetPrimesメソッドについては,

「ループを2から回せばmaxが1以下の場合、ループが回らず、素数は0件になるし、こっちの方がエレガントだよ」

なるほど〜.そんなわけで最終的には以下のようになりました.

class Program
{
  static List<int> GetPrimes(int maxNum)
  {
    List<int> primeList = new List<int>();
    for (int i = 2; i <= maxNum; i++)
    {
      if (primeList.TrueForAll(delegate(int j) { return i % j != 0; }))
      {
        primeList.Add(i);
      }
    }
    return primeList;
  }

  static void Main(string[] args)
  {
    foreach (int prime in GetPrimes(100))
    {
      Console.Write("{0},", prime);
    }
    Console.WriteLine("");
  }
}

雑感

ListのExists/TrueForAllよりも,LINQのAny/Allのほうが名前のセンスがいいな〜.数学の∃/∀と直感的に結びつきやすいですから.なんか楽しくなってきました.