【问题标题】:Get previous element of a dictionary获取字典的前一个元素
【发布时间】:2012-02-11 22:25:29
【问题描述】:

出于多种原因,我拥有Dictionary<string, string>,并且我正在 foreach 循环中对其进行检查。我没有办法(至少我没有找到一个聪明的解决方案)用列表、数组或Dictionary<int, string> 替换它。字典由服务器名称、包状态(2 个字符串)组成。

我正在尝试获取 foreach 循环中的前一个元素,以便将其与当前元素进行比较。

我的代码:

foreach (KeyValuePair <string,string> pair in packageDistribution) { 
     if (pair.Value == "package distribution complete") { 
          // print pair.Key + " - Installed"; 
     } else {
         // print pair.Key + " - " + pair.Value
     } 
     if (i%3==0) "OR" (i== packageDistribution.count) { 
       // print the values \n 
     } 
}

我需要将它们 3 x 3 分组以节省空间,但我的问题是即使当前元素与前一个元素不同,我也想打印到新行:

pair.Key.substring(0,4) != previousElement.substring(0,4)

我的服务器看起来像 NLDN1234, NLDN1235, NSTM2345, NSTM9874,我想根据它们的名称对它们进行分组。

有人有聪明的建议吗?

【问题讨论】:

  • 为前一个元素声明一个变量并保留它。
  • 字典是有序遍历的错误数据结构
  • 这真的是你的代码吗? if (i%3==0) "OR" (i== packageDistribution.count) 看起来不像 valid c#。
  • 如果我不能索引字典怎么办。实际上,即使我将 dictionary.keys.toArray() > array[0] 保存到变量中,如何在 foreach 循环中正确更新它?
  • 不是“或”而是||。我在我的 macbook 中找不到条形图:)

标签: c# dictionary foreach iteration


【解决方案1】:

我认为您的代码没有按照您的想法进行 - 无法保证对字典中的键值对进行排序;它们可以按任何顺序排列,甚至可能在您的应用程序的不同运行中按不同顺序排列。

如果您需要按特定顺序排列它们,则应使用OrderBy() 明确对其进行排序,如果需要对它们进行分组,请使用GroupBy() ...

var groupsInOrder 
    = packageDistribution.GroupBy(p => p.Key.SubString(0,4))
        .OrderBy(g => g.Key);
foreach(var group in groupsInOrder)
{ 
    int index = 0;
    foreach(var pair in group)
    {
        // Handle item
        if (++index%3==0)
        {
            // New line
        }
    }
    // New line
}

【讨论】:

  • 或者,如果您使用的是 .NET 4,请使用新的 SortedDictionary
  • 它们已经排序,因为它们来自使用 order by 子句运行的 SQL 查询。订购不是问题。我的问题是将具有不同主机名(第一个 4 位)的服务器打印到新行。为了检测服务器是否有不同的主机名,我需要将其名称与之前打印/存储的服务器主机名进行比较
  • @user,关键是字典不保留顺序。您可能已经按给定的顺序将元素放入其中,但这并不意味着元素以相同的顺序从其中出来。那不是它的工作。它的工作是提供基于唯一键的快速值查找。
  • 我听从了你的建议,但是使用 group by 后如何访问 Value 属性?
  • 而且我不想将它们全部归为一个条目。我需要将它们全部打印出来,但我想在服务器名称与之前的名称不同时立即换行,超过 4 位数字(首字母缩写)。 for 循环听起来很合乎逻辑,但我不知道如何使用需要访问键和值的字典来做到这一点
【解决方案2】:

这应该很简单,

 Dictionary<string, string> svrs = new Dictionary<string, string>();
            svrs.Add("NLDN1234", "ok");
            svrs.Add("NLDN1235", "ok");
            svrs.Add("NSTM2345", "ok");
            svrs.Add("NSTM9874", "ok");

            SortedDictionary<string, string> sortedSvrs = new SortedDictionary<string, string>(svrs);

            for (int i = 0; i < sortedSvrs.Keys.Count; i++)
            {
                var key = sortedSvrs.Keys.ElementAt(i);
                Console.WriteLine(key +" " + sortedSvrs[key]);
                // any extra operation
                //
            }

【讨论】:

    【解决方案3】:

    你不能使用传统的 for 循环吗?

    for(int i = 0; i < packageDistribution.Count; i++) {
        if(i != 0) {
            // check for packageDistribution at i against i-1
        }
    }
    

    这样的?

    【讨论】:

    • 字典不能*以这种方式使用。 (*除非字典是&lt;int, X&gt;,并且键是0..n-1,此时你可能只需要一个数组,而字典是毫无意义的。在这种情况下,字典是&lt;string, string&gt;,所以for直接反对就对了。)
    • 相反,您可以使用 packageDistribution.Keys.Count ,从索引中查找键并从键中查找值
    猜你喜欢
    • 1970-01-01
    • 2013-06-03
    • 2012-12-08
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    相关资源
    最近更新 更多