How do I get previous key from SortedDictionary?

后端 未结 7 2228
误落风尘
误落风尘 2020-12-18 20:46

I have dictionary containing key value pairs.

SortedDictionary dictionary=new SortedDictionary();
dictionary.Add(1,33);
diction         


        
相关标签:
7条回答
  • 2020-12-18 20:47
    KeyValuePair<int, int> lookingForThis = dictionary
      .Reverse()
      .SkipWhile(kvp => kvp.Key != 4)
      .Skip(1)
      .FirstOrDefault();
    
    0 讨论(0)
  • 2020-12-18 20:53

    I was also looking for an answer to this problem, and I thought a better solution than all of the answers here is to use the TreeDictionary<K, V> from the C5 Collections (GitHub/NuGet), which is an implementation of a red-black tree.

    It has Predecessor/TryPredecessor and WeakPredessor/TryWeakPredecessor methods (as well as equivalent methods for successors) which does exactly what you want.

    For example:

    TreeDictionary<int,int> dictionary = new TreeDictionary<int,int>();
    dictionary.Add(1,33);
    dictionary.Add(2,20);
    dictionary.Add(4,35);
    
    // applied to the dictionary itself, returns KeyValuePair<int,int>
    var previousValue = dictionary.Predecessor(4);
    Assert.Equals(previousValue.Key, 2);
    Assert.Equals(previousValue.Value, 20);
    
    // applied to the keys of the dictionary, returns key only
    var previousKey = dictionary.Keys.Predecessor(4);
    Assert.Equals(previousKey, 2);
    
    // it is also possible to specify keys not in the dictionary
    previousKey = dictionary.Keys.Predecessor(3);
    Assert.Equals(previousKey, 2);
    
    0 讨论(0)
  • 2020-12-18 20:53

    You could loop through the dictionary and keep track of values, I guess. Something like this:

    public int GetPreviousKey(int currentKey, SortedDictionary<int, int> dictionary)
    {
        int previousKey = int.MinValue;
        foreach(KeyValuePair<int,int> pair in dictionary)
        {
            if(pair.Key == currentKey)
            {
                if(previousKey == int.MinValue)
                {
                    throw new InvalidOperationException("There is no previous key.");
                }
                return previousKey;
            }
            else
            {
                previousKey = pair.Key;
            }
        }
    }
    

    However, this is a pretty odd operation to require. The fact that you need it might be pointing at a problem with your design.

    0 讨论(0)
  • 2020-12-18 20:55

    I would prefer to use linq if that's the case... try this it will surely work

    SortedDictionary<int,int> dictionary = new SortedDictionary<int,int>();
    dictionary.add(1, 33);
    dictionary.add(2, 20);
    dictionary.add(4, 35);
    
    int SelectedKey = 4;
    
    var ResutValue = ( from n in dictionary    
                   where n.Key < TheSelectedKey
                   select n.Value).Last();
    
    this.txtResult.Text = ResultValue.ToString();
    
    0 讨论(0)
  • 2020-12-18 21:01

    Dictionary<TKey,TValue> is unsorted, so there is no previous thing for some item. Instead you can use SortedDictionary<TKey,TValue>.

    EDIT: Sorry I read the title only LOL.

    If you have to use LINQ:

    int givenKey = 4;
    var previousItem = dict.Where((pair, index) => 
                                       index == dict.Count || 
                                       dict.ElementAt(index + 1).Key == givenKey)
                           .FirstOrDefault();
    
    0 讨论(0)
  • 2020-12-18 21:05

    How about this? I havent tested it though, but should give something to start think in this direction. Hope it helps.

            int input = 4;
            List<int> lKeys = dictionary.Keys.ToList();
            int reqIndex = lKeys.IndexOf(input) - 1;
            int reqAnswer = dictionary[reqIndex];
    

    test for other conditions like if (reqIndex != -1) etc..

    0 讨论(0)
提交回复
热议问题