2011-08-22 84 views
0

我有一個列表,我得到列表中的每個項目在foreach循環中。詞典檢查

private void saveButton_Click(object sender, EventArgs e) 
    { 
      if (saveFile1.ShowDialog() == DialogResult.OK) 
      { 
       StreamWriter sw = new StreamWriter(saveFile1.FileName); 
       int i = 1; 

       Dictionary<string, int> dictionary = new Dictionary<string, int>(); 

       foreach (var line in theFinalList) 
       { 
        //compareList.Add(line.PartNumber[]); 
        if (!line.Name.Contains("FID") || !line.PartNumber.Contains("FIDUCIAL") || 
         !line.PartNumber.Contains("EXCLUDES") || !line.PartNumber.Contains("excludes")) 
        { 
         //This doesn't work obviously.. :/ 
         sw.WriteLine("({0} 0 1 1 0 0 0 0 \"{1}\" \"{2}\" \"\" {3} 0 0 0 0 0)", 
          i, line.PartDescription, line.PartNumber, partNumberOccurrences); 
        } 

        i++; 
       } 
      } 

,我使用的字典存儲在字典中的線的各個部分,然後遞增,每當發現爲重複的itemCounter有麻煩。我試圖做這樣的事情,但我無法弄清楚它的邏輯。

我想只輸出部分編號1的時間以及它發生的次數以及與partNumber在同一行的相應值。

輸出應該是這樣的:

(1 0 1 1 0 0 0 0 "2125R_1.0" "136380" "" 18 0 0 0 0 0) 
(2 0 1 1 0 0 0 0 "2125R_1.0" "128587" "" 41 0 0 0 0 0) 
(3 0 1 1 0 0 0 0 "2125R_1.0" "138409" "" 11 0 0 0 0 0) 
(4 0 1 1 0 0 0 0 "2125R_1.0" "110984" "" 8 0 0 0 0 0) 
(5 0 1 1 0 0 0 0 "3216R_1.3" "114441" "" 6 0 0 0 0 0) 
(6 0 1 1 0 0 0 0 "3216C_1.3" "2006722" "" 16 0 0 0 0 0) 
(7 0 1 1 0 0 0 0 "3216C_1.3" "135732" "" 6 0 0 0 0 0) 

誰能幫我創建一個字典來做到這一點?

回答

0
foreach (string word in lineList) 
{ 
    if (dictionary.ContainsKey(word) 
     dictionary[word]++; 
    else 
     dictionary[word] = 1; 
} 
1

我想你想是這樣的:

int value; 
if (!dictionary.TryGetValue(line.PartNumber, out value)) 
{ 
    value = 0; 
} 
dictionary[line.PartNumber] = value + 1; 
+0

你不需要'if';如果找不到密鑰,'TryGetValue'將把'default(int)'(aka 0)放入'value'中。 – dlev

+2

不過,它的可讀性更強,如果... –

+0

@Paolo嗯......好吧,公平的觀點:) – dlev

2

你也可以爲您的項目一個新的類,並存儲這些項目的列表,然後使用LINQ組的結果 - 你可能會或可能不會發現它更符合邏輯:

public class MyItem 
{ 
    public string Name { get; set; } 
    public string PartNumber { get; set; } // I did this as string rather than int 
    public string Description { get; set; } 
} 

public List<MyItem> items = new List<MyItem>(); 

然後,你似乎要被分組的項目(本例使用LINQ和假定您已經填充了項目列表):

IEnumerable<IGrouping<int, MyItem>> grouped = items 
    .GroupBy(t => Convert.ToInt32(t.PartNumber)) 
    .OrderBy(t => t.Key); 

foreach(var item in grouped) 
{ 
    Console.WriteLine("Number of Occurances:" + item.Key); 
    Console.WriteLine("Name: " + item.ElementAt(0).Name); 
    Console.WriteLine("Description: " + item.ElementAt(0).Description); 
    Console.WriteLine("\n --------------------------------- \n"); 
} 

本示例假定具有相同零件號的所有零件都具有相同的名稱和說明。

+0

我試着將代碼插入代碼中,但它似乎與'.Orderby(t => t.Key)'部分有問題......你能幫我解決這個問題嗎?問題? – theNoobGuy

+0

它給了什麼問題? – AndrewC

+0

'不能隱式轉換類型'System.Linq.IOOrderedEnumerable >'to'System.Collections.Generic.IEnumerable >」。存在明確的轉換(你是否缺少演員?)是說什麼.. – theNoobGuy

0

你也可以使用匿名類型和linq一起給你一個更好的解決方案。這裏假設你的行是製表符分隔的一個例子。

 var lines = new[] 
         { 
          "R80\t123456\tsomething here1", 
          "R81\t123456\tsomething here1", 
          "R81\t123456\tsomething here1", 
         }; 

     var items = lines.Select(i => i.Split('\t')).Select(i => new {Name = i[0], PartNumber = i[1], Description = i[2]}); 

     var outLines = 
      items.GroupBy(i => i.Name).Select(
       i => 
       string.Format("{0}\t{1}\t{2}\t{3}", i.First().Name, i.First().PartNumber, i.First().Description, 
           i.Count())); 

     foreach (var outLine in outLines) 
     { 
      Console.WriteLine(outLine); 
     } 

     Console.Read(); 
+0

當使用這個我似乎得到一個輸出是:** System.Linq.Enumerable + WhereSelectEnumerableIterator'2 [System.Linq.IGrouping'2 [System.String,<> f__AnonymousType0'3 [System.String,System.String ,System.String]],System.String] ** – theNoobGuy

+0

這是因爲您正在編寫集合對象而不是集合中的每個項目。我編輯了這個例子來使這個更加明顯 – johnB