我很好奇是否有更好看的,更简单的(在Linq:p的情况下可能存在争议)方式来选择当前未选择的任何下一个Dictionary元素。
假设我有一个Dictionary<string,bool>
,我已经存储了一个默认/第一个键,现在我需要选择具有值“true”的下一个元素(如果到达结尾则重新开始) 没有foreach / loop 循环。
我知道字典没有订购,但在这种情况下我不在乎。只要nextKey != currentKey
和搜索距currentKey
更远,而不是从FirstOrDefault
开始(除非它是字典的“结尾”)我现在很好。
示例:
public Dictionary<string,bool> myDic = new Dictionary<string,bool>(5);
myDic.Add("test1", false);
myDic.Add("test2", true);
myDic.Add("test3", false);
myDic.Add("test4", true);
myDic.Add("test5", true);
现在我选择第一个Key,如果是,我会单独保存。 否则OR或请求 - 我需要找到从当前选中的值开始具有值true的下一个Key。所以我要说我选择使用ElementAt(1)
,它是test1
。由于Value
是false
,我需要获得true
的下一个test2
。get-eventlog -computername dc-01 -logname security | ?{$_.eventid -eq "4674"} |
select machinename,eventid,@{n='AccountName';e={$_.ReplacementStrings[1]}},entrytype,message |
convertto-html | out-file c:\test.html
。Get-EventLog "Security" -before 4/10/2013 -InstanceId 4663 | % {
New-Object psobject -Property @{
Index = $_.Index
TimeGenerated = $_.TimeGenerated
"Account Name" = $_.ReplacementStrings[1]
"Object Type" = $_.ReplacementStrings[5]
"Object Name" = $_.ReplacementStrings[6]
}
} | export-csv c:\export.csv -NoTypeInformation
正如我所说,我想避免像foreach / for / while / etc这样的显式循环。
答案 0 :(得分:2)
我要做的只是用value==true
选择所有值,跳到currentKey元素,然后获取下一个元素,如:
public Dictionary<string,bool> myDic = new Dictionary<string,bool>(5);
myDic.Add("test1", false);
myDic.Add("test2", true);
myDic.Add("test3", false);
myDic.Add("test4", true);
myDic.Add("test5", true);
string currentKey;
KeyValuePair<string,bool> res;
if (currentKey==null)
{
res=myDic.Where(x => x.Value).FirstOrDefault();
}
else
{
res=myDic.Where(x => x.Value).SkipWhile(x => x.Key !=
currentKey).Skip(1).FirstOrDefault();
}
if (res.Key!=null)
{
currentKey=res.Key;
Console.WriteLine(currentKey);
}
else
{
Console.WriteLine("Result is null");
}
答案 1 :(得分:0)
试试这个:
var result = yourDictionary.SkipWhile(_keyValue => _keyValue .Key != currentKey).Where(_keyValue => _keyValue.Value == true);
答案 2 :(得分:0)
使用枚举器:
Dictionary<string, bool> dict = new Dictionary<string, bool>();
List<string> keys = dict.Keys.AsEnumerable().ToList();
List<string>.Enumerator dictEnumerator = keys.GetEnumerator();
答案 3 :(得分:0)
有了@ Abdullah-dibas的想法,这可能适合你。
var m = myDic.SkipWhile(x => x.Value && x.Key != myDic.First().Key)?.First();
我发现你使用的是C#2.0,因此需要进行更改:
var m = myDic.SkipWhile(x => x.Value && x.Key != myDic.First().Key);
if (m != null && m.Count() > 0)
{
var element = m.First();
//And do whatever
}
答案 4 :(得分:0)
简单回答是:否,如果不使用任何 foreach
/循环,则无法执行此操作。
考虑所有linq-to-object代码都是某种foreach
/循环循环。
但是如果你不想在当前页面内看到这些循环,你可以制作这样的扩展方法:
public static TKey GetNextKeyByValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary,
TKey currentKey, TValue nextValue)
{
var ckFounded = false;
// if `currentkey` is last key of dictionary it will check for value from start again
for (var i = 0; i < 2; i++)
{
foreach (var pair in dictionary)
{
if (ckFounded && pair.Value.Equals(nextValue))
{
return pair.Key;
}
if (pair.Key.Equals(currentKey) || (currentKey?.Equals(default(TKey)) ?? true))
{
ckFounded = true;
}
}
}
throw new Exception("Key not found");
}
像这样使用它:
//var nextKey = yourDictionary.GetNextKeyByValue(currentKey, nextValue);
var firstKey = myDic.GetNextKeyByValue(default(string) /* or null */, true);
var nextKey = myDic.GetNextKeyByValue(firstKey, true);