TakeWhile
扩展方法在其工具提示中有以下注释:“元素的索引用于谓词函数的逻辑”。请注意,此工具提示在常规工具提示中不可见,但仅在变量sortedDictionary
的列表成员的intellisense列表的工具提示中可见。
这正是与SortedDictionary
一起寻找的东西。
var first = sortedDictionary.First(kv => kv.Key.ToString().StartsWith(searchkey));
var last= sortedDictionary.Last(kv => kv.Key.ToString().StartsWith(searchkey));
var range = sortedDictionary.TakeWhile(kv => kv.Key.ToString().StartsWith(searchkey));
找到第一个和最后一个项目并且正确,但我的收藏范围是空的 这有什么不对?我期望一个范围包括第一个和最后一个之间的所有项目,包括它们。
我仍然可以使用第一个和最后一个找到范围,但TakeWhile
使用索引而First
和Last
显然不会。
编辑:“使用索引”原来与排序无关,但您可以在查询中使用索引。例如。当我用SortedDictionary
替换SortedList
时,我可以这样做:
int ix1 = sortedList.IndexOfKey(first.Key);
int ix2 = sortedList.IndexOfKey(last.Key);
var range = sortedList.SkipWhile((x, i) => i < ix1).TakeWhile((x, i) => i <= ix2);
还可以使用SortedDictionary
:
var range = sortedList.SkipWhile(x => !x.Key.ToString().StartsWith(searchkey))
.TakeWhile(x => x.Key.ToString().StartsWith(searchkey));
我将不得不测试哪种方法更快,还必须测试Where查询。
答案 0 :(得分:1)
TakeWhile()
将从序列的开头开始,只要它们都满足谓词。如果第一项未通过谓词,则结果为空。您所谈论的描述来自overload,其中包含一个索引(您未使用)。
只是正常过滤项目,它应该产生你期望的范围(由于排序)。
var range = sortedDictionary.Where(kv => kv.Key.ToString().StartsWith(searchkey));
答案 1 :(得分:1)
如果序列中的第一个元素与谓词不匹配,则TakeWhile方法将退出:
将序列中的元素返回为 只要指定的条件为真
First方法将采用与谓词匹配的第一个元素:
返回a中的第一个元素 满足指定的序列 条件
与First方法相反,Last方法将采用与谓词匹配的最后一个元素:
返回序列的最后一个元素 满足指定条件
我猜测TakeWhile正在提前退出,因为它们在迭代开始时没有符合条件的元素。
如果你想要你的例子中第一个和最后一个元素之间的元素范围(包括第一个和最后一个项目),那么试试这个:
var range = sortedDictionary.SkipWhile( x => !x.Equals( first ) )
.TakeWhile( x => !x.Equals( last ) )
.Concat( new SortedDictionary<string, string> { { last.Key, last.Value } } );
或者你不能像我一样过度思考这个问题,并使用Where
方法中的{{1}}方法使用更简单的方法。
答案 2 :(得分:0)
您阅读的工具提示是针对重载的,其谓词的Int32为参数MSDN Link
你介意发布一些代码,看看为什么它会返回一个空范围?以下代码按预期工作(我复制/粘贴您的代码)。
var sortedDictionary = new SortedDictionary<string, string>();
var searchkey = "test";
sortedDictionary.Add("test1", "value");
sortedDictionary.Add("test2", "value");
sortedDictionary.Add("test3", "value");
sortedDictionary.Add("test4", "value");
var first = sortedDictionary.First(kv => kv.Key.ToString().StartsWith(searchkey));
var last = sortedDictionary.Last(kv => kv.Key.ToString().StartsWith(searchkey));
var range = sortedDictionary.TakeWhile(
kv => kv.Key.ToString().StartsWith(searchkey));
foreach (var c in range)
{
Console.WriteLine(c);
}
Console.ReadKey();