词典检查

问题描述:

我有一个列表,我得到列表中的每个项目在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) 

谁能帮我创建一个字典来做到这一点?

foreach (string word in lineList) 
{ 
    if (dictionary.ContainsKey(word) 
     dictionary[word]++; 
    else 
     dictionary[word] = 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

你也可以为您的项目一个新的类,并存储这些项目的列表,然后使用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

你也可以使用匿名类型和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