使用多个相同键轻松查找值的最佳集合类型是什么?

发布于 2024-08-24 06:56:09 字数 1111 浏览 7 评论 0 原文

我有如下的文本文档,其中包含单个多个变量:

title:: Report #3
description:: This is the description.
note:: more information is available from marketing
note:: time limit for this project is 18 hours
todo:: expand the outline
todo:: work on the introduction
todo:: lookup footnotes

我需要迭代此文本文档的行并填充 <具有这些变量的strong>集合,目前我正在使用字典

public Dictionary<string, string> VariableNamesAndValues { get; set; }

但这不适用于多个相同上例中的“note”和“todo”等键,因为键在字典中必须是唯一

什么是最好的集合,这样我不仅可以获得像这样的单个值:

string variableValue = "";
if (VariableNamesAndValues.TryGetValue("title", out variableValue))
    return variableValue;
else
    return "";

而且我还可以获得像这样的多个值:

//PSEUDO-CODE:
List<string> variableValues = new List<string>();
if (VariableNamesAndValues.TryGetValues("note", out variableValues))
    return variableValues;
else
    return null;

I have text documents like the following which contain single and multiple variables:

title:: Report #3
description:: This is the description.
note:: more information is available from marketing
note:: time limit for this project is 18 hours
todo:: expand the outline
todo:: work on the introduction
todo:: lookup footnotes

I need to iterate through the lines of this text document and fill a collection with these variables, currently I'm using a Dictionary:

public Dictionary<string, string> VariableNamesAndValues { get; set; }

But this doesn't work on multiple, identical keys such as "note" and "todo" in the above example since keys have to be unique in a Dictionary.

What is the best collection so that I can not only get single values like this:

string variableValue = "";
if (VariableNamesAndValues.TryGetValue("title", out variableValue))
    return variableValue;
else
    return "";

but that I can also get multiple values out like this:

//PSEUDO-CODE:
List<string> variableValues = new List<string>();
if (VariableNamesAndValues.TryGetValues("note", out variableValues))
    return variableValues;
else
    return null;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

獨角戲 2024-08-31 06:56:09

如果您的键和值是字符串,则使用 NameValueCollection< /a>.它支持给定键的多个值。

这不是世界上最高效的收集。特别是因为它是一个非泛型类,使用了大量虚拟方法调用,并且 GetValues 方法将为其返回值分配数组。但除非您需要最好的性能集合,否则这肯定是最方便的集合,可以满足您的要求。

If your keys and values are strings then use a NameValueCollection. It supports multiple values for a given key.

It's not the most efficient collection in the world. Particularly because it's a non-generic class, uses a lot of virtual method calls, and the GetValues method will allocate arrays for its return values. But unless you require the best performing collection, this is certainly the most convenient collection that does what you ask.

哭了丶谁疼 2024-08-31 06:56:09

您可以制作 key: 字符串和 value: 字符串列表的字典

Dictionary>

EDIT 1 & 2:
如果您可以使用 .NET 3.0 或更高版本,我想到了更好的解决方案。
这是一个 LINQ 示例(我在没有 Visual Studio 的情况下输入了它,所以我希望它能够编译;)): 对

string[] lines = File.ReadAllLines("content.txt");
string[] separator = {":: "};
var splitOptions = StringSplitOptions.RemoveEmptyEntries;

var items = from line in lines
            let parts = line.Split(separator, splitOptions)
            group parts by parts[0] into partGroups
            select partGroups;

上面示例的简短说明:

  • 从字符串数组中的文件中获取所有行
  • 定义一些拆分选项(以保持示例可读)
  • 对于lines数组中的每一行,将其拆分为“::”
  • 将拆分结果分组到第一个拆分部分(例如标题、描述、注释...)
  • 将分组的项目存储在 items 变量中

结果LINQ 查询是 IQueryable>>
结果中的每个项目都有一个 Key 属性,其中包含该行的键(标题、说明、注释...)。
可以枚举包含所有值的每个项目。

You can make a Dictionary of key: string and value: List of String

Dictionary<string,List<string>>

EDIT 1 & 2:
I've thought of a better solution if you can use .NET 3.0 or higher.
Here's a LINQ example (I typed it without Visual Studio, so I hope it compiles ;)):

string[] lines = File.ReadAllLines("content.txt");
string[] separator = {":: "};
var splitOptions = StringSplitOptions.RemoveEmptyEntries;

var items = from line in lines
            let parts = line.Split(separator, splitOptions)
            group parts by parts[0] into partGroups
            select partGroups;

A short explanation of the example above:

  • Get all lines from the file in a String array
  • Define some Split options (to keep the example readable)
  • For each line in the lines array, split it on the ":: "
  • Group the results of the split on the first split part (e.g. title, description, note, ...)
  • Store the grouped items in the items variable

The result of the LINQ query is a IQueryable<IGrouping<string, IEnumberable<string>>>.
Each item in the result has a Key property containing the key of the line (title, description, note, ...).
Each item can be enumerated containing all of values.

榆西 2024-08-31 06:56:09

您可以使用 Lookup

ILookup<string, string> lookup = lines.Select(line => line.Split(new string[] { ":: " })
                                      .ToLookup(arr => arr[0], arr => arr[1]);
IEnumerable<string> notes = lookup["note"];

请注意,此集合是只读的

You could use a Lookup<TKey, TElement> :

ILookup<string, string> lookup = lines.Select(line => line.Split(new string[] { ":: " })
                                      .ToLookup(arr => arr[0], arr => arr[1]);
IEnumerable<string> notes = lookup["note"];

Note that this collection is read-only

紫南 2024-08-31 06:56:09

您可以使用 PowerCollections,它是一个开源项目,具有可以解决您的问题的 MultiDictionary 数据结构。

这是如何使用它的示例

注意:Jon Skeet 之前在回答这个问题时建议过这一点。

You may use PowerCollections which is an open source project that has a MultiDictionary data structure which solves your problem.

Here is a sample of how to use it.

Note: Jon Skeet suggested it before in his answer to this question.

挽清梦 2024-08-31 06:56:09

我不是 c# 专家,但我认为 Dictionary>

或某种 HashMap> 可能工作。
例如(Java伪代码):
aKey aValue
aKey anotherValue

if(map.get(aKey) == null)
{
   map.put(aKey, new ArrayList(){{add(aValue);}});
} 
else 
{
   map.put(aKey, map.get(aKey).add(anotherValue));
}

或类似的东西。
(或者,最短路线:

map.put(aKey, map.get(aKey) != null ? map.get(aKey).add(value) : new ArrayList(){{add(value);}});

I'm not a c# expert, but I think Dictionary<string, List<string>>

or some kind of HashMap<string, List<string>> might work.
For example (Java pseudocode):
aKey aValue
aKey anotherValue

if(map.get(aKey) == null)
{
   map.put(aKey, new ArrayList(){{add(aValue);}});
} 
else 
{
   map.put(aKey, map.get(aKey).add(anotherValue));
}

or something similar.
(or, the shortest way:

map.put(aKey, map.get(aKey) != null ? map.get(aKey).add(value) : new ArrayList(){{add(value);}});
Spring初心 2024-08-31 06:56:09

我过去曾使用 Dictionary> 来获取多个值。我很想知道是否有更好的东西。

以下是如何模拟仅获取一个值的方法。

public static bool TryGetValue(this Dictionary<string, HashSet<string>> map, string key, out string result)
{
    var set = default(HashSet<string>);
    if (map.TryGetValue(key, out set))
    {
        result = set.FirstOrDefault();
        return result == default(string);
    }
    result = default(string);
    return false;
}

I have used Dictionary<string, HashSet<string>> for getting multiple values in the past. I would love to know if there is something better though.

Here is how you can emulate getting only one value.

public static bool TryGetValue(this Dictionary<string, HashSet<string>> map, string key, out string result)
{
    var set = default(HashSet<string>);
    if (map.TryGetValue(key, out set))
    {
        result = set.FirstOrDefault();
        return result == default(string);
    }
    result = default(string);
    return false;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文