2013-06-29 93 views
0

我有解析兩個文件(.txt和的.xls),存儲有各種不同的領域爲對象C#,對象的兩個列表中找到這兩個對象一個變量之間的差異

List<AcsRecord> Textrecords = AcsFileParser.Parsefile(path1); 
List<ExcelRecord> Execelrecords = excelFileParser.Parsefile(path2); 

作爲一個例子的程序的AcsRecord是:

public string EID {get; set;} 
public string Name {get; set;} 

Excel記錄有一個類似的名稱記錄。我想,主要找到所有在AcsRecord中找到的在Excelrecord中找不到的名稱。使用linq join,我只能找到那些相同的東西。我不確定如何引用每個記錄中的名稱字段。也許類似於!contains()? 謝謝。

回答

9

是的,你可以這樣做:

var excelNames = new HashSet<string>(excelRecords.Select(x => x.Name)); 
var textRecordsNotInExcel = textRecords.Where(t => !excelNames.Contains(t.Name)) 
             .ToList(); 

創建這裏HashSet<string>的要點是使Contains檢查很便宜,順便說一句。 A List<string>也可以工作(例如var excelNames = excelRecords.Select(x => x.Name).ToList();),但它將涉及每個文本記錄的所有Excel記錄名稱的O(N)檢查。

編輯:如果你只想要名稱不Excel中的文本記錄,它更容易:

var missingNames = textRecords.Select(t => t.Name) 
           .Except(excelRecords.Select(e => e.Name)) 
           .ToList(); 
+0

真棒。我可以把這個變量放入一個foreach循環來打印它們到控制檯嗎? – Cassus

+0

@jonskeet - 一旦你有HashSet是不是更快使用'Except()'? – Hogan

+0

@Hogan - HashSet沒有'Except'方法(即使用'IEnumerable.Except'即O(n)),雖然它有'ExceptWith',但也是O(n)。 HashSet.Contains是O(1),所以在大多數情況下,使用HashSet.Contains會更有效率,我相信。 – keyboardP

0

你是對的,你應該!Contains()像這樣:

var query= from ar in Textrecords 
      let er=Excelrecords.Select(r=>r.Name) 
      where !er.Contains(ar.Name) 
      select ar; 
相關問題