【问题标题】:Get first KeyValuePair in a dictionary that has a specific value在具有特定值的字典中获取第一个 KeyValuePair
【发布时间】:2012-11-29 09:47:30
【问题描述】:

我正在用 C#/.NET 4.5 编写一个应用程序,我有一个这样定义的字典:

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

我的整数键是连续且唯一的,除了空字符串,我的值也是唯一的。例如:

Key     Value
  0     AAAAAAAAAA
  1     BBBBBB
  2     (empty string)
  3     CCCCCCCCCCCCCCCCCCCCCCCC
  4     DDDDDDDDDDDDDDD
  5     EEEEEEEEEEEEEEEEEEE
  6     (empty string)

当我有一个新字符串要添加到字典中时,我需要将它分配给一个值为(空字符串)的键。理想情况下,我想在这样的密钥的第一个实例中执行此操作。我目前正在像这样循环浏览我的字典:

int keyNumber;

foreach (KeyValuePair<int, string> pair in d)
{
    if (pair.Value == string.Empty)
    {
        keyNumber = pair.Key;
        break;
    }
}

d[keyNumber] = "new string goes here!";

这可行,但有没有更好(或更快)的方法来完成同样的事情?如果这实际上是最好的方法,是否可以将其缩短为 LINQ 表达式?

编辑 ---------------------------------- -------------------------------------------

我遗漏了可能需要解释的重要内容。加载到我的字典中的值实际上是从包含固定长度字节数组的二进制文件中加载的,这些字节数组包含 ASCII 字符串。该文件将始终由 5000000 字节或 100000 个总字符串组成,每个字符串 50 个字节。文件结构由将使用文件的设备上的一些硬件限制决定。因此,我的字典中每个 KeyValuePair 的键实际上用于确定文件的偏移量,当用户完成更改时,我需要在其中写入任何更改。例如,使用 4 的键,然后乘以 50 到 200 字节的起始偏移量。然后我将修改后的字符串写回到那个位置。很抱歉在我的原始帖子中省略了这一点。

【问题讨论】:

  • 听起来您的键与您的值无关,顺序也无关紧要……那您为什么要使用Dictionary?为什么不直接使用List,索引可以是你的Key
  • 实际上,我的键和值确实需要有关系。我遗漏了一些细节,但加载到字典中的数据来自一个二进制文件,该文件由包含我的 ASCII 字符串的固定长度字节数组组成(总共 100000 个字符串,每个 50 字节)。我的字典中的键用于确定二进制文件更改应写入的位置(例如,偏移量 4 * 50 = 200,然后我读取 50 个字节并解码字符串“DDDDDDDDDDDDDDD”)。这有意义吗?
  • 我严重怀疑 LINQ 会更快。它也必须枚举和比较。所以你确定你不会用完string.Empty?
  • 是的,string.Empty 可能用完。文件大小是固定的,只能容纳 100,000 个 ASCII 编码的字符串,每个字符串 50 个字节。如果没有 string.Empty 值,则用户必须通过删除一些现有数据来为更多数据腾出空间。听起来很疯狂,但这是一项要求。
  • 如果键是整数顺序的、唯一的并且以 0 开头,为什么不直接使用 string[100000] 并让序数位置成为键。 U 声明了硬件限制。

标签: c# .net dictionary iteration key-value


【解决方案1】:
d[d.FirstOrDefault(x => string.IsNullOrEmpty(x.Value)).Key] = "My String";

但是,字典实际上是用来存储真正的键值对的。列表听起来更适合您的情况,您似乎只需要存储值。即便如此,列表元素仍然可以通过索引访问,并且您可以包含空元素,因此(根据您所说)似乎没有理由坚持使用字典。

【讨论】:

    【解决方案2】:

    Dictionary 可能不是您尝试做的最佳选择。试试简单的List&lt;&gt; 或数组。

    Dictionary 是一种将一个唯一值映射到另一个非唯一值的优化方法。如果您尝试做更多的事情,那么您最好实现自己的集合。

    【讨论】:

      【解决方案3】:

      如果你知道会有一个空字符串值的条目,你可以使用:

      var kvp = d.First(p => p.Value == string.Empty);
      d[kvp.Key] = "new string goes here!";
      

      【讨论】:

        【解决方案4】:

        我不推荐它,正如 cmets 所说,您应该使用列表。但这里有两个例子:

          Dictionary<int, string> d = new Dictionary<int, string>();
          string valueToBeInserted = "randomstring";
          var keyValuePair = d.FirstOrDefault(c => c.Value == string.Empty);
          d[keyValuePair.Key] = valueToBeInserted;
        

        简化:

         Dictionary<int, string> d = new Dictionary<int, string>();
         string valueToBeInserted = "randomstring";
         d[d.FirstOrDefault(c => c.Value == string.Empty).Key] = valueToBeInserted;
        

        【讨论】:

          猜你喜欢
          • 2015-03-31
          • 1970-01-01
          • 1970-01-01
          • 2014-03-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多