C# 如何从SortedDictionary获取上一个密钥?

C# 如何从SortedDictionary获取上一个密钥?,c#,.net,linq,sorteddictionary,C#,.net,Linq,Sorteddictionary,我有包含键值对的字典 SortedDictionary<int,int> dictionary=new SortedDictionary<int,int>(); dictionary.Add(1,33); dictionary.Add(2,20); dictionary.Add(4,35); SortedDictionary dictionary=新的SortedDictionary(); 增补(1,33); 增补(2,20); 增补(4,35); 我想从已知的键值中

我有包含键值对的字典

SortedDictionary<int,int> dictionary=new SortedDictionary<int,int>();
dictionary.Add(1,33);
dictionary.Add(2,20);
dictionary.Add(4,35);
SortedDictionary dictionary=新的SortedDictionary();
增补(1,33);
增补(2,20);
增补(4,35);
我想从已知的键值中获取上一个键值对。在上面的例子中,如果我有键4,那么我如何获得

字典
是未排序的,因此某些项没有前面的内容。相反,您可以使用

编辑:对不起,我只看了标题LOL

如果必须使用LINQ:

int givenKey = 4;
var previousItem = dict.Where((pair, index) => 
                                   index == dict.Count || 
                                   dict.ElementAt(index + 1).Key == givenKey)
                       .FirstOrDefault();

我想,你可以在字典中循环查找并跟踪值。大概是这样的:

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;
        }
    }
}
public int GetPreviousKey(int currentKey,SortedDictionary字典)
{
int previousKey=int.MinValue;
foreach(字典中的KeyValuePair对)
{
if(pair.Key==currentKey)
{
如果(previousKey==int.MinValue)
{
抛出新的InvalidOperationException(“没有以前的键”);
}
返回上一个键;
}
其他的
{
previousKey=pair.Key;
}
}
}
然而,这是一个非常奇怪的操作要求。您需要它的事实可能表明您的设计存在问题。

KeyValuePair lookforthis=dictionary
KeyValuePair<int, int> lookingForThis = dictionary
  .Reverse()
  .SkipWhile(kvp => kvp.Key != 4)
  .Skip(1)
  .FirstOrDefault();
.Reverse() .SkipWhile(kvp=>kvp.Key!=4) .Skip(1) .FirstOrDefault();
使用
SortedDictionary
很难有效地实现这一点,因为它是作为一个二进制搜索树实现的,不会公开前辈或后辈

当然,您可以枚举每个KeyValuePair,直到找到“已知”密钥。使用一点LINQ,这看起来像(假设该键确实存在并且不是第一个键):

IndexOfKey
在键列表上运行二进制搜索,在
O(log n)
time中运行。其他所有操作都应该在固定时间内运行,这意味着整个操作应该在对数时间内运行



否则,您必须自己实现/找到一个BST集合,它确实公开了前辈/后辈。

如果是这样的话,我宁愿使用linq。。。试试这个,它肯定会有用的

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();
SortedDictionary dictionary=新的SortedDictionary();
增加(1,33);
增加(2,20);
增加(4,35);
int SelectedKey=4;
var ResutValue=(从字典中的n开始)
其中n.键<所选键
选择n.Value).Last();
this.txtreult.Text=ResultValue.ToString();

这个怎么样?虽然我还没有测试过,但应该给出一些东西来开始朝这个方向思考。希望能有帮助

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

测试其他条件,如if(reqIndex!=-1)等。

我也在寻找这个问题的答案,我认为比这里所有答案更好的解决方案是使用来自(/)的,这是红黑树的实现

它有
前置
/
trypredeccessor
WeakPredessor
/
tryweakpreducer
方法(以及后继者的等效方法),这些方法正是您想要的

例如:

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);
TreeDictionary=新的TreeDictionary();
增补(1,33);
增补(2,20);
增补(4,35);
//应用于字典本身,返回KeyValuePair
var previousValue=字典.前置(4);
Assert.Equals(previousValue.Key,2);
Assert.Equals(previousValue.Value,20);
//应用于字典的键,仅返回键
var-previousKey=dictionary.Keys.previous(4);
Assert.Equals(previousKey,2);
//也可以指定字典中没有的键
previousKey=dictionary.Keys.previous(3);
Assert.Equals(previousKey,2);

SortedDictionary dictionary=新的SortedDictionary();我想这些答案可以解释如何做你想做的事。是否有任何Linq查询可以给我以前的密钥。user578083,我已经在下面使用Linq查询给出了一个答案请查看。。。好的:)+1。我只想指出OP的问题没有真正意义。虽然此答案将返回它们之前的配对,但当您向字典中添加项时,之前的配对将不断变化。我认为需要对OP试图做的事情做更多的澄清。我认为它应该是
.SkipWhile(kvp=>kvp.Key!=4)。跳过(1)
如果有人不知道什么是弱前置项,那么它是第一个等于或小于传递值的项。(严格的)前置项是刚好小于传递值的项。同样,对于后继者来说,C5集合也很酷,但它们在最新版本的文档中存在问题,因此请节省您的时间,克隆源代码,并查看源代码。尝试在一个接受
dict
givenKey
作为我的字典和密钥的函数中使用它,并以字符串形式返回
previousItem
,因为我有一本
字典。我收到一个错误:
无法将类型“System.Collections.Generic.KeyValuePair”隐式转换为“string”
。所以这不仅仅返回密钥-我确认它返回整个KeyValuePair。所以在我的例子中,我做了
KeyValuePair tempKVP=MoveToPreviousKey(myDict,givenKey)
然后
字符串previousKey=tempKVP.Key。工作得很好。有人。
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();
        int input = 4;
        List<int> lKeys = dictionary.Keys.ToList();
        int reqIndex = lKeys.IndexOf(input) - 1;
        int reqAnswer = dictionary[reqIndex];
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);