2014-03-28 26 views
1

如何在SortedSet中訪問項目?如何在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; 
} 
+0

此外,這會根據輸入查找的元素不一定是在(例如,如果集合僅包含「蘋果」和「貓」,即使「熊」本身不在列表中,如果集合僅包含「蘋果」和「貓」,則「熊」的輸入將顯示「蘋果」和之後的「貓」),但這對搜索幫手來說不一定是壞事 – Sam

+0

@Sam是的,我確實在想這件事,那就是所期望的行爲。在完整的代碼和回車鍵用於添加到列表並實際將值添加到數據庫。我考慮一個選項卡和項目不存在將項目添加到列表中,但不會將其添加到數據庫。例如,用戶有一個他們想要鍵入的可能值的列表。 – Paparazzi

+0

@Sam認爲他們進入b,只想到達第一個b,但沒有理由列出名單上的b – Paparazzi

回答

1

使用由提問者提供的邏輯,這裏是提供ElementBeforeElementAfter訪問任何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); 
} 

,這是可擴展到包含任何類型的對象集,不止是字符串

+0

讓我看看你的答案並進行測試。至於添加和刪除我認爲只是從基地的人。我不熟悉擴展方法,所以它會帶我一點。爲什麼不製作一個實現SortedSet的集合? – Paparazzi

+0

@Blam你可以查看http://msdn.microsoft.com/en-us/library/bb383977.aspx,但你應該能夠將該類添加到你的項目中,並直接在你的'SortedSet'上調用新方法對象 – Sam

+0

是的我已經使用了擴展方法。仍然要花一點時間來測試它在真實應用程序中的使用情況,比我發佈的示例稍微複雜一些。 – Paparazzi

1

如果我理解正確,您試圖獲得值的索引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; 
} 
+1

我想到的是直接進入到下一個項目,而不是首先確定項目。請參閱我的問題的更新。 – Paparazzi

+0

@Blam這絕對是一種優雅的方式來實現你的目標!我喜歡它,並認爲你應該用解決方案發布你的問題的答案,並從你的問題中刪除編輯。這肯定會檢索直接跟隨的元素,並避免擴展方法的所有塊。 – Sam