Get first element from a dictionary
我有以下声明:
1
| Dictionary <string, Dictionary <string, string>> like = new Dictionary <string, Dictionary <string, string>>(); |
我需要得到第一个元素,但不知道键或值。最好的方法是什么?
- 为字典定义"First"。
- 字典是无序的。
- Try FirstOrDefault();
- 相关(双向飞碟除外):stackoverflow.com/q/436954/1001985
- 当您知道字典中只有一个项时,使用first()是有意义的,因为您已经在字典上完成了.count。那么您不需要对一个项目执行foreach循环,只需使用first()。
- @Louiseeggleton这正是我使用此解决方案的方式。感谢您对OP的问题保持冷静。
- 如果您知道它只有一个项,那么也可以使用single()或singleOrDefault()而不是first()。
注意,调用First实际上是调用IEnumerable的LINQ扩展,该扩展由Dictionary实现。但对于字典来说,"第一"没有定义的含义。根据这个答案,最后添加的项最终是"第一"(换句话说,它的行为类似于堆栈),但这是特定于实现的,它不是保证的行为。换言之,假设您要先调用任何已定义的项,这将是自找麻烦——使用它应该被视为从字典中获取随机项,正如下面Bobson所指出的那样。但是,有时这很有用,因为您只需要字典中的任何项目。
只需使用Linq First():
1 2 3
| var first = like.First();
string key = first.Key;
Dictionary<string,string> val = first.Value; |
注意,在字典上使用First可以得到KeyValuePair,在本例中是KeyValuePair>。
还请注意,通过将First与linq OrderBy结合,您可以从First的使用中获得特定的含义:
1
| var first = like.OrderBy(kvp => kvp.Key).First(); |
- 我建议进行编辑,将val更改为它的正确值(因为它是一个字符串),但我想它被拒绝了?
- @是的,因为val是一个Dictionary,而like是一个Dictionary>。
- 哦,我的错,抱歉打扰你了。
- @字典中的dbaseman没有第一对。仅仅因为你在Dictionary上打了First,并不意味着你实际上在字典里得到了第一个条目。你在字典里有一个条目,但不是第一个条目。没有第一个项目,因为字典是无序的。这种类型的回答只会进一步伤害行动,因为他们会继续相信他们实际上得到了"第一"项,即使不存在这样的事情。这个问题的正确答案是没有第一项。
- @Servy-我可以想到一个场景,在字典上调用First是值得的:当你想要访问一个键或值对象的属性时,这些对象在所有对象上都应该是相同的(即在子字典中对父对象的后向引用)。
- @波布森,我还能想起其他人。关键是你需要意识到它不是"第一个项目",而是"任意项目"。只要你清楚它在做什么,并且对它满意,那就没事了。行动计划明确表示他想要"第一件物品"。这种事不存在。如果他要求"任意项目",那么这个答案将是100%正确的。
- -1=>+1用于添加OrderBy()。
- 我得到错误'type'system.collections.generic.dictionary
- @波布森这很有意义。我有一本关于部门(字符串)和部门代码(字符串)的字典。我公司的人可以只为一个部门工作,也可以考虑在少数几个部门工作。我检查字典条目的计数,如果只有一个条目,那么我希望这个部门不知道它的键或值。如果他们有不止一个,那么我会选择一个,然后把它送回。
- 谢谢,我的用例是实现一个dbobj.selectFirst()方法(一个只返回第一行结果的第一列的select方法)。如果调用函数决定使用一个产生的项多于它最初应该产生的项的查询,那么方法的性质允许我将这种未定义的行为传递给调用函数。在这种情况下,我可以使用.first()、.last()、.rnd()…这并不重要。在实践中,它总是(到目前为止)准确地返回您想要的东西,在本例中,因为字典对象倾向于保持创建它们的顺序。
- 对于其他人来说,我们并没有真正得到第一个-如果你使用.OrderBy并订购它,那么你想要的就在上面,是的,你得到的是第一个。如果你只是有一本字典,就像我做的,你也会得到第一本。
对于任何一个来这里的人来说,他们想要一个无LINQ的方法从字典中获取一个元素。
1 2 3 4 5 6 7
| var d = new Dictionary <string, string>();
d .Add("a", "b");
var e = d .GetEnumerator();
e .MoveNext();
var anElement = e .Current;
// anElement/e.Current is a KeyValuePair<string,string>
// where Key ="a", Value ="b" |
我不确定这是否是特定于实现的,但是如果您的字典没有任何元素,那么Current将包含一个KeyValuePair,其中键和值都是null。
(我看了linq的First方法背后的逻辑,并通过LinqPad 4进行了测试)
- 枚举器是IDisposable对象,因此您应该在这里使用using构造。
虽然您可以使用First(),但字典本身没有顺序。请改用OrderedDictionary。然后你可以做FirstOrDefault。这样就有意义了。
- 我不知道"安全"。"有意义"会更合适。首先,对于Dictionary,你只是不知道它是什么,不像有序的字典,在这种情况下,First有一个有意义的值。
编辑:使用OrderedDictionary。
最好使用FirstOrDefault()来检索第一个值。
前任:
1 2 3
| var firstElement = like.FirstOrDefault();
string firstElementKey = firstElement.Key;
Dictinary<string,string> firstElementValue = firstElement.Value; |
- FirstOrDefault()的优点是,如果字典中没有默认值,它将给出默认值。
- 然而,由于字典是无序的,所以在字典中没有"第一"项这样的东西。不存在此类项目。你可以从字典中得到一个条目,但是你需要有一个有序的数据结构来获得"第一个"。
- 我同意。拥有一个orderedDictionary对于"第一"来说是有意义的。
字典没有定义项的顺序。如果您只需要一个项目,请使用字典的Keys或Values属性来选择一个项目。
1 2
| Dictionary <string, Dictionary <string, string>> like = new Dictionary <string, Dictionary <string, string>>();
Dictionary <string, string> first = like .Values.First(); |
- .values.first()不存在…是否使用System.Collection.Generic?
- "不存在"是什么意思?记住,first()是一个扩展方法,因此必须在using指令中包含using System.Linq。
我会找到在字典中查找第一个元素的简单方法:)
1 2 3 4 5 6 7 8
| Dictionary<string, Dictionary<string, string>> like =
newDictionary<string,Dictionary<string, string>>();
foreach(KeyValuePair<string, Dictionary<string, string>> _element in like)
{
Console.WriteLine(_element.Key); // or do something
break;
} |