2010年10月19日 星期二

LINQ not in

今天因為處理繪圖需要針對集合做not in的運算,主要是因為TeeChart提供的API實在太弱了,所以有些運算只好自己土法煉鋼。故事大綱是這樣的,我有100個Point,符合條件的其中的20個我想要拿掉,如果不使用LINQ的話,做法如下

    //針對Point的定義
    class PointF
    {
        public double X { set; get; }
        public double Y { set; get; }

        public override bool Equals(object obj)
        {
            PointF inObj = obj as PointF;
            return this.X == inObj.X && this.Y == inObj.Y;
        }
    }

    List points = new List(); 
    List flagPoint = new List();  
    for (int i = 0; i < 100; i++) 
    {
       PointF point = new PointF { X = i, Y = i };
       points.Add(point);
       if (i % 5 == 0) //製造符合條件的point
          flagPoint.Add(point);
    }
    Console.WriteLine("total point {0}",points.Count.ToString());
    Console.WriteLine("flag point {0}", flagPoint.Count.ToString());
    //比對以移除符合條件的點
    for (int i = 0; i < points.Count; i++)
    {
       for (int j = 0; j < flagPoint.Count; j++)
       {
          if (points[i].X == flagPoint[j].X && points[i].Y == flagPoint[j].Y)
          {
              points.Remove(points[i]);
              break;
          }
       }
    }
            
    Console.WriteLine("points point {0}", points.Count.ToString());
    Console.WriteLine("flag point {0}", flagPoint.Count.ToString());

    Console.ReadKey();
其結果如下
改成使用LINQ的話
 
 List points = new List();
 List flagPoint = new List();
 for (int i = 0; i < 100; i++)
 {
     PointF point = new PointF { X = i, Y = i };
     points.Add(point);
     if (i % 5 == 0)
        flagPoint.Add(point);
  }
  Console.WriteLine("total point {0}",points.Count.ToString());
  Console.WriteLine("flag point {0}", flagPoint.Count.ToString());

  points = (from c in points
            where !flagPoint.Contains(c)
           select c).ToList();

  Console.WriteLine("points point {0}", points.Count.ToString());
  Console.WriteLine("flag point {0}", flagPoint.Count.ToString());

  Console.ReadKey();

結果會與上面一樣

透過LINQ,程式碼可讀性會提高很多,不過這裡的not in的用法第一次用,所以稍微花了點時間找