Tag Archives: LINQ

C# Distinct List of Object

今日在Code Review 同事的Code 時候發現了一個有趣的寫法
他想做的是 Return 一個Distinct 左既 List Of Object

好直接既想法是使用 Distinct

List.Distinct();

之後發現Distinct 是不能 Distinct Object的
同事的寫法是用了 List 加 GroupBy 和Select First()

List.GrounBy(x=> x.key).Select(x => x.First())

之後發現.. 原來我們可以使用 GroupBy 加 First 來做到 Distinct Object的效果
以下是我的 Code Sample

void Main()
{
	var list = new List<Example>();
	list.Add(new Example() {Id=1, Name="Example 1", Comment="Comment 1" });
	list.Add(new Example() {Id=1, Name="Example 1", Comment="Comment 1" });
	list.Add(new Example() {Id=1, Name="ExamplE 1", Comment="Comment 2" });
	list.Add(new Example() {Id=2, Name="Example 2", Comment="Comment 3" });
	list.Add(new Example() { Id = 2, Name = "example 2", Comment = "Comment 3" });
	list.Add(new Example() { Id = 3, Name = "Example 3", Comment = "Comment 3" });
	list.Add(new Example() { Id = 4, Name = "Example 4", Comment = "Comment 3" });
	list.Add(new Example() { Id = 5, Name = "Example 5", Comment = "Comment 3" });

	Console.WriteLine("Use List.Distinct()");
	list.Distinct().Dump();

	Console.WriteLine("Use Group By Fields");
	list.GroupBy(x => new {x.Id, Name=x.Name}).Select(x =>x.First()).Dump();

	Console.WriteLine("Use Group By and make it ignore case");
	list.GroupBy(x => new {x.Id, Name=x.Name.ToLower()}).Select(x =>x.First()).Dump();
}

public class Example
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Comment {get;set;}
}

Output:

Hope you find it useful

Linq compare 2 lists – .Net Check if Items Not exist on current List – 如何在2個Lists 中找出和第二個List不相同的Item 項目

之前和大家介紹了怎樣可以找出在2個List of String上找出2個List 都有的 Item 出來

今天想和大家介紹怎樣從兩個Lists 中找出 第一個List上 在第二個List裡面沒有的 Item

我們可以使用 ListExcept 功能

			// Source List with String A,B,C,D,E
			List listA = new List();
            listA.Add("A");
            listA.Add("B");
            listA.Add("C");
            listA.Add("D");
            listA.Add("E");

			// List To Compare with String 1,A,4,E,5
            List listB = new List();
            listB.Add("1");
            listB.Add("A");
            listB.Add("4");
            listB.Add("E");
            listB.Add("5");

			// Retrieve the List of String which does not appear on the second List
            List matchList = listA.Except(listB).ToList().ForEach(Console.WriteLine);


Linq compare 2 lists - .Net Check if Items Not exist on current List - 如何在2個Lists 中找出和第二個List不相同的Item 項目
Happy Coding

LINQ try to get a list of int from string – 如何使用Linq在String上取出所有數字出來

今天要為同事解決一個 在ASP.Net MVC [.Net]將String 轉成List of Int的問題

情況是這樣的:
公司的一個ASP.Net MVC 的Project 上..客戶會在 WebGrid上的checkbox上選擇需要的東西..
我的同事便寫了一個隱藏的field 每當客戶選擇或取消選項時..
他用了Javascript 來把數據append 到隱藏的field上
他便用”|” 來把數據分隔
但是我們還是要做一些Validation
避免數據有問題時..會令到這個程式碼/程序出現問題
E.G.
1|ab|| | 3 |4|
有空格或有字母時..當把數據轉到List Of Int時便會出現錯誤了

由於他工作放大假中..
所以我便要去解決他沒有解決的問題了
就是用.net去把這一個 String轉成 List of Int..

開頭我都有一些不知如何是好..
因為可以用一個比較簡單的方法..
但是可能要寫多很多的程式碼
就是先建立一個StringArray..
之後用Int.TryParse來把 成功認到是Int的 數據加進另一個List of Int上..
感覺不太好..

做了一些research 之後終於找到解決方法了:
解決方法:

我們可以嘗試使用LINQ 的方法去解決這個問題

  // Input
  string tempInput = "1|ab|| | 3 |4|";

  // This value is used for int.TryParse reference
  int tempVal=0;
  List intList = (from i in tempInput.Split('|').ToList()
                                          where int.TryParse(i, out tempVal)
                                          select  int.Parse(i)).ToList();
  int noOfInt = intList.Count();
  // Output number of integer recognised 
  Console.WriteLine("No of Int: " + noOfInt.ToString());
  
  for(int i = 0; i< intList.Count(); i++){
  	// Output the recognised integer one by one
  	Console.WriteLine(intList[i].ToString());
  }
  

Use Linq to extract List of Integer from string

Happy Coding

Linq compare 2 lists – .Net Check if Items exist on Both Lists – .Net如何在2個Lists 中找出相同的Item 項目

今天需要寫一個功能去看看2個 List of String 上有那些String 是2個Lists內都有的

做了一會research後 終於找到解決方法了

我們可以使用 ListIntersect 功能

Linq - to get matched item from 2 lists of string

E.G.

            	// Source List with String A,B,C,D,E
            			List listA = new List();
            listA.Add("A");
            listA.Add("B");
            listA.Add("C");
            listA.Add("D");
            listA.Add("E");

            			// List To Compare with String 1,A,4,E,5
            List listB = new List();
            listB.Add("1");
            listB.Add("A");
            listB.Add("4");
            listB.Add("E");
            listB.Add("5");

          			// Retrieve the List of String which appear on both List
            List matchList = listA.Intersect(listB).ToList();

            for (int i = 0; i < matchList.Count; i++)
            {
               			// Output the list of matched string
                Console.WriteLine(matchList[i]);
            }

Happy Coding

.Net Get All files under the directory Improved version—使用.Net找出 資料夾/文件夾入所有檔案改進版

很久之前寫過一個網誌是介紹如何找出 資料夾/文件夾入所有檔案

VB.Net Get All files under the directory —使用VB.Net找出 資料夾/文件夾入所有檔案

之前是用一個叫Recursion 的方法來取得資料夾裡面的資料夾內的檔案…
最近另外一個Project上又要做一個差不多的功能
令使用者可以看到資料夾入有什麼檔案可以下載
回看返之前的Blog 這個功能應該不用寫到那麼複雜的
還有這個function的效能其實也不太好

所以便去做一下research看看有沒有更好的解決方法了

解決方法:
原來我做可以使用DirectoryInfo中的GetFiles 方法
我們還可以設定一些變數去選擇要找出資料夾入..那一類型的檔案等等

E.G.
使用DirectoryInfoGetFiles功能
DirectoryInfo dirInfo = new DirectoryInfo(“資料夾路徑”);
第一個變數是Filter File Extension “*.*” 是選擇所有檔案 而 “*.txt”則是只選擇 .txt
List FileInfoList = dirInfo.GetFiles(Extension Filter, SearchOption).ToList();
C#


// Initialise DirectoryInfo 設定將要找出檔案的資料夾
            DirectoryInfo dirInfo = new DirectoryInfo(txt_Folder.Text.Trim());

            // 使用DirectoryInfo 的GetFiles功能
            // 第一個變數是Filter File Extension "*.*" 是選擇所有檔案 而 "*.txt"則是只選擇 .txt
            // 第二個變數是SearchOption 有 AllDirectories 和 TopDirectoryOnly 2個選擇,
            // 我們想找出資料夾入所有的檔案..包括資料夾內的資料夾所以我們會用到AllDirectories
            List<FileInfo> fileInfoList = dirInfo.GetFiles("*.*", SearchOption.AllDirectories).ToList();

            // 如果你只需要檔案名稱的話可以使用Directory Instead of Directory List.. 他會
            // List<String> fileInfoList = Directory.GetFiles(txt_Folder.Text.Trim(), "*.*", SearchOption.AllDirectories).ToList();

            dgv_FileList.DataSource = fileInfoList;

Hope you find it useful