проверить другие условия, такие как if (reqIndex! = -1) и т. д.

я есть словарь, содержащий пары ключ-значение.

SortedDictionary<int,int> dictionary=new SortedDictionary<int,int>();
dictionary.Add(1,33);
dictionary.Add(2,20);
dictionary.Add(4,35);

Я хочу получить предыдущую пару ключ-значение из известного значения ключа. В приведенном выше случае, если у меня есть ключ 4, то как я могу получить<2,20>?

 Mitch Wheat18 янв. 2011 г., 06:11
Смею спросить "Почему?"
 PramodChoudhari18 янв. 2011 г., 06:10
SortedDictionary <int, int> dictionary = new SortedDictionary <int, int> ();
 Carls Jr.18 янв. 2011 г., 10:11
user578083, я дал ответ ниже, используя запрос linq, проверь ... ок :)
 PramodChoudhari18 янв. 2011 г., 06:18
Есть ли запрос Linq, который даст мне предыдущий ключ.
 Cody Gray♦18 янв. 2011 г., 06:15
Я думаю, что ответы наэтот вопрос объясни как делать что хочешь.

Ответы на вопрос(7)

и я подумал, что лучшим решением, чем все ответы здесь, является использованиеTreeDictionary<K, V> изC5 Коллекции (GitHub/NuGet), которая является реализацией красно-черного дерева.

В нем естьPredecessor/TryPredecessor а такжеWeakPredessor/TryWeakPredecessor методы (а также эквивалентные методы для наследников), который делает именно то, что вы хотите.

Например:

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);
 nawfal11 июн. 2014 г., 13:56
Если кто-то не знает, что такое слабый предшественник, это первый пунктравно или меньше переданное значение. (Строгим) предшественником является элемент простоменьше, чем переданное значение. Аналогично для преемников.
Решение Вопроса

SortedDictionary<TKey, TValue> поскольку оно реализовано в виде двоичного дерева поиска, которое не раскрывает предшественников или преемников.

Конечно, вы можете просто перечислять каждую KeyValuePair, пока не найдете «известный» ключ. С небольшим количеством LINQ это будет выглядеть (при условии, что ключ определенно существует, а не первый):

SortedDictionary<int, int> dictionary = ...
int knownKey = ...

var previousKvp = dictionary.TakeWhile(kvp => kvp.Key != knownKey)
                            .Last();

Если эти предположения не верны, вы можете сделать:

var maybePreviousKvp = dictionary.TakeWhile(kvp => kvp.Key != knownKey)
                                 .Cast<KeyValuePair<int, int>?>()
                                 .LastOrDefault();

(Проверь этоmaybePreviousKvp != null чтобы убедиться, что предыдущий KeyValuePair был успешно получен.)

Но это не будет эффективным вообще.

Если это возможно, рассмотрите возможность использованияSortedList<TKey, TValue> вместо этого (очевидно, это может быть невозможно, если вы не можете использовать его медленные вставки и удаления). Эта коллекция поддерживает эффективный поиск ключа и значенияупорядоченный индекс, так как он реализован в виде растущего массива. Тогда ваш запрос становится таким простым:

SortedList<int, int> dictionary = ...
int knownKey = ...

int indexOfPrevious = dictionary.IndexOfKey(knownKey) - 1;

// if "known" key exists and isn't the first key
if(indexOfPrevious >= 0)
{
   // Wrap these in a KeyValuePair if necessary
   int previousKey = dictionary.Keys[indexOfPrevious];
   int previousValue = dictionary.Values[indexOfPrevious];      
}

IndexOfKey запускает бинарный поиск по списку ключей, работает вO(log n) время. Все остальное должно выполняться за постоянное время, то есть вся операция должна выполняться за логарифмическое время.

В противном случае вам придется реализовать себя / найти коллекцию BST, которая раскрывает предшественников / преемников.

хотя, но должен дать кое-что, чтобы начать думать в этом направлении. Надеюсь, это поможет.

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

проверить другие условия, такие как if (reqIndex! = -1) и т. д.

KeyValuePair<int, int> lookingForThis = dictionary
  .Reverse()
  .SkipWhile(kvp => kvp.Key != 4)
  .Skip(1)
  .FirstOrDefault();
 TomTom18 янв. 2011 г., 06:52
---------------
 Gabe18 янв. 2011 г., 07:09
Я думаю, что это должно быть.SkipWhile(kvp => kvp.Key != 4).Skip(1)
 Rob♦18 янв. 2011 г., 06:42
+1. Хотел бы отметить, что вопрос ОП не имеет смысла. В то время как этот ответ вернет их пару раньше, пара раньше будет постоянно меняться при добавлении элементов в словарь. Я думаю, что нужно больше разъяснений о том, что пытается сделать ФП
 Amy B18 янв. 2011 г., 14:38
Спасибо, Гейб. Editted.

Dictionary<TKey,TValue> не сортируется, значит нетпредыдущий вещь для какого-то предмета. Вместо этого вы можете использоватьSortedDictionary<TKey,TValue>.

РЕДАКТИРОВАТЬ: Извините, я прочитал заголовок только LOL.

если тыиметь использовать LINQ:

int givenKey = 4;
var previousItem = dict.Where((pair, index) => 
                                   index == dict.Count || 
                                   dict.ElementAt(index + 1).Key == givenKey)
                       .FirstOrDefault();
 PramodChoudhari18 янв. 2011 г., 06:15
Да, я уже использую SortedDictionary.
 Adam Lear♦18 янв. 2011 г., 06:13
Он уже использует SortedDictionary.
 vapcguy22 сент. 2016 г., 23:29
Пробовал использовать это в функции, которая принялаdict а такжеgivenKey как мой словарь и ключ, с которого я начинал, и вернутьpreviousItem как строка, так как у меня есть словарь<string, DateTime>, Я получаю ошибку:Cannot implicitly convert type 'System.Collections.Generic.KeyValuePair<string, System.DateTime>' to 'string', Так что это не просто возвращает ключ - я подтвердил, что он возвращает весь KeyValuePair. Так что в моем случае я сделалKeyValuePair<string, DateTime> tempKVP = MoveToPreviousKey(myDict, givenKey); а потомstring previousKey = tempKVP.Key;, Работал отлично. HTH кто-то.

если это так ... попробуйте это, безусловно, будет работать

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();

вы могли бы перебирать словарь и отслеживать значения. Что-то вроде этого:

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;
        }
    }
}

Однако это довольно странная операция. Тот факт, что вам это нужно, может указывать на проблему с вашим дизайном.

 PramodChoudhari18 янв. 2011 г., 06:27
Привет, дорогой, ваше решение работает спасибо Alots ... :)

Ваш ответ на вопрос