如何在SortedSet中访问项?
string entry;
private SortedSet<string> pastEntriesSS = new SortedSet<string>(StringComparer.OrdinalIgnoreCase);
entry = entry.Replace("t", "").TrimStart();
entry = Regex.Replace(entry, @"s+", " ");
string s = pastEntriesSS.FirstOrDefault(x => x.StartsWith(entry.Trim(), StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrEmpty(s))
{
if(string.Compare(s,entry.Trim(),true) == 0)
{
// what I what here is the entry after s
// how do I get the index of s
int index = -1;
s = pastEntriesSS.ElementAt(index + 1);
if (!string.IsNullOrEmpty(s)) entry = s;
}
else
entry = s;
}
这是用于自动补全的如果他们点击了完全匹配的选项卡那么我想要得到下一个
我想我看错了
这就是我想出来的
entry = entry.Replace("t", "").TrimStart();
entry = Regex.Replace(entry, @"s+", " ");
string s = pastEntriesSS.FirstOrDefault(x => x.StartsWith(entry, StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrEmpty(s))
{
if(string.Compare(s,entry,true) == 0)
{ // it they tabbed on an exact match then go to next or prior
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
s = pastEntriesSS.Reverse().FirstOrDefault(x => string.Compare(x, s, true) < 0);
}
else
{
s = pastEntriesSS.FirstOrDefault(x => string.Compare(x, s, true) > 0);
}
if (!string.IsNullOrEmpty(s)) entry = s;
}
else
entry = s;
}
使用请求器提供的逻辑,这里是一种使用扩展方法为ElementBefore
和ElementAfter
提供对任何SortedSet
的访问的方法:
public static class BeforeAfterExtension
{
//The true workhorse of the code!
public static T ElementBefore<T>(this SortedSet<T> mySet, T val, IComparer<T> comparer)
{
//we are getting the first element el such that it is before
//the provided value val. We must reverse the set because
//otherwise, the first element in the set is always the first
//to be less than the provided value.
return mySet.Reverse().FirstOrDefault(el => comparer.Compare(el, val) < 0);
}
//Contains all the actual logic
public static T ElementAfter<T>(this SortedSet<T> mySet, T val, IComparer<T> comparer)
{
//we are getting the first element el such that it is after
//the provided value val.
return mySet.FirstOrDefault(el => comparer.Compare(el, val) > 0);
}
//use the existing logic, but use the default comparer for the set
public static T ElementBefore<T>(this SortedSet<T> mySet, T val)
{
return ElementBefore(mySet, val, mySet.Comparer);
}
//use the existing logic, but use the default comparer for the set
public static T ElementAfter<T>(this SortedSet<T> mySet, T val)
{
return ElementAfter(mySet, val, mySet.Comparer);
}
//provide a condition that the element must already exist in the set
//Consider a set of strings containing only "apple" and "cat"
//without forcing the element to exist in the set, we could search for
//the element before "bear" and get "apple" even though "bear" is not
//in the set. Forcing the element to exist by setting mustExist=true
//would return null if the element is not there already
public static T ElementBefore<T>(this SortedSet<T> mySet, T val, bool mustExist, IComparer<T> comparer) {
{
if (mustExist)
{
if (mySet.Contains(val))
{
//take advantage of existing logic
return ElementBefore(mySet, val, comparer);
}
else
{
return null;
}
}
else
{
//take advantage of existing logic
return ElementBefore(mySet, val, comparer);
}
}
//provide a condition that the element must already exist in the set
//Consider a set of strings containing only "apple" and "cat"
//without forcing the element to exist in the set, we could search for
//the element after "bear" and get "cat" even though "bear" is not
//in the set. Forcing the element to exist by setting mustExist=true
//would return null if the element is not there already
public static T ElementBefore<T>(this SortedSet<T> mySet, T val, bool mustExist, IComparer<T> comparer) {
{
if (mustExist)
{
if (mySet.Contains(val))
{
//take advantage of existing logic
return ElementAfter(mySet, val, comparer);
}
else
{
return null;
}
}
else
{
//take advantage of existing logic
return ElementAfter(mySet, val, comparer);
}
}
//just use the default set comparer
public static T ElementBefore<T>(this SortedSet<T> mySet, T val, bool mustExist)
{
//take advantage of existing logic
return ElementBefore(mySet, val, mustExist, mySet.Comparer);
}
//just use the default set comparer
public static T ElementAfter<T>(this SortedSet<T> mySet, T val, bool mustExist)
{
//take advantage of existing logic
return ElementAfter(mySet, val, mustExist, mySet.Comparer);
}
}
还有一些额外的方法允许自定义所使用的比较器,并要求该元素存在于集合中。
现在需要的是
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
s = pastEntriesSS.ElementBefore(s);
}
else
{
s = pastEntriesSS.ElementAfter(s);
}
这可以扩展到包含任何类型对象的集合,而不仅仅是字符串
如果我理解正确,您正试图获得值s
的索引,然后在它之后检索元素。
您可以通过检索s
的索引的扩展方法来实现这一点:
public static class MyExtensions
{
public static int IndexOf<T>(this SortedSet<T> mySet, T val)
{
int index = 0;
foreach (T el in mySet) {
if (mySet.Comparer.Compare(el, val) == 0) {
return index;
}
index++;
}
return -1;
}
public static int IndexOf<T>(this SortedSet<T> mySet, T val, IEqualityComparer<T> comparer)
{
int index = 0;
foreach (T el in mySet) {
if (comparer.Equals(val, el)) {
return index;
}
index++;
}
return -1;
}
}
让你在你的集合中调用IndexOf
:
int index = pastEntriesSS.IndexOf(s);
if (index >= 0)
{
s = pastEntriesSS.ElementAt(index + 1);
if (!string.IsNullOrEmpty(s)) entry = s;
}