2013-02-18 2 views
-1

Я хочу знать, есть ли способ сохранить значение перечислителя пар ключевых значений, итерации через словарь. Я хочу сохранить ключ и значение перечислителя в некоторой переменной. Каково решение? То, что я хотел сделать, - это повторить через словарь, чтобы иметь ссылку на текущую пару ключевых значений и следующую пару ключевых значений в словаре. Я не знаю, почему он не работает.Словарь итератор в C#

Вот как могло бы выглядеть решение:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections; 
using System.Diagnostics; 

namespace WellPuzzle 
{ 

    class Solution 
    { 
     Hashtable h1 = new Hashtable(); 
     List<int> listofitemstoremove = new List<int>(); 

     Dictionary<int, int> d1 = new Dictionary<int, int>(); 

     public void falling_disks(int[] A, int[] B) 
     { 
      var itemstoremove = new List<int>(); 

      var en = d1.GetEnumerator(); 
      int count = 0; 
      for (int i = 0; i <= A.Length - 1; i++) 
      { 
       d1.Add(count++, A[i]); 
      } 
      //for each incoming element in array 
      foreach (int ele in B) 
      { 
       //store prev as current position of enumerator 
       var prev = new KeyValuePair<int, int>(); 
       prev = en.Current; 
       //check if it is possible to iterate to next element in dictionary 
       if (en.MoveNext()) 
       { 
        //loop till end of dictionary 
        while (en.MoveNext()) 
        { 
         //if current value of enumerator in dictionary is less than incoming            element and check if corroesponding key for that value is in hashtable or not 
         if (en.Current.Value <= ele && !(checkifthatvalueisfilled(en.Current.Key))) 
          continue; 
         else 
         {//if current enumerator value is greater than incoming element from array B then remove all elements from prev reference till end of dictionary 
          h1.Add(en.Current.Key, true); 
          listofitemstoremove.Add(en.Current.Key); 
         } 
         prev = en.Current; 
        } 

        if (!(h1.ContainsKey(en.Current.Key))) 
        { 
         h1.Add(en.Current.Key, true); 
         listofitemstoremove.Add(en.Current.Key); 
        } 
       } 
       else 
       { 
        h1.Add(prev.Key, true); 
        listofitemstoremove.Add(prev.Key); 
       } 
       foreach (int item in listofitemstoremove) 
       { 
        for (int i = item; i < d1.Count; i++) 
        { 
         d1.Remove(i++); 
        } 
       } 
      } 

      Console.WriteLine(h1.Count); 
     } 






     public bool checkifthatvalueisfilled(int value) 
     { 
      if (h1.ContainsValue(h1.ContainsKey(value)) == true) 
       return true; 
      else return false; 
     } 
    } 


    class Program 
    { 
     static void Main(string[] args) 
     { 
      int[] A = new int[] { 5, 6, 4, 3, 6, 2, 3 }; 
      int[] B = new int[] { 2, 3 }; 
      Solution s1 = new Solution(); 
      s1.falling_disks(A, B); 
     } 
    } 
} 
+3

Ваш код написанный? Конечно нет. У вас есть 'en', который вводится в IEnumerator, который используется для хранения KeyValuePair, и у вас есть' next', пытающийся сохранить результат метода возврата пустоты. Что вы на самом деле пытаетесь достичь? Конец, а не средства. –

+1

Кажется, что вы пытаетесь лечить словарь как нечто, имеющее нумерационный счетчик (или в порядке). Не делай этого. В зависимости от того, что вы хотите, посмотрели, будет ли работать многомерный массив 'int [,]'? – Earlz

+0

похоже, что вы пытаетесь установить текущую позицию перечислителя, подобно тому, как вы устанавливаете указатель на C++. Если это то, что вы хотите, это невозможно в C#; вы можете переместить перечислитель только на следующий элемент; вы не можете просто установить его на какой-то произвольный элемент. – Servy

ответ

1

есть хорошая причина, вы не можете использовать: -

// Replace TKey and TValue with the types from the dictionary 
TKey previousKey; 
TValue previousValue; 

bool first = true; 

foreach(var key in dictionary.Keys) 
{ 
    var value = dictionary[key]; 

    if (!first) 
    { 
    ... // Do whatever you need to do with the keys and values 
    } 

    previousKey = key; 
    previousValue = value; 
    first = false; 
} 

(Заметим, однако, что вы, вероятно, придется .OrderBy(...) ваш .Keys для этого, чтобы сделать какой-либо смысл)

0

Как Iain, а другой приближается, вы также можете сделать это так (как Иэн, это дает предыдущий и текущий, а не текущий и следующий, но они в значительной степени то же самое):

using System; 
using System.Collections.Generic; 

namespace Demo 
{ 
    public static class Program 
    { 
     private static void Main(string[] args) 
     { 
      var d1 = new Dictionary<int, int> {{1, 1}, {2, 2}, {3, 3}, {4, 4}}; 
      bool isFirst = true; 
      var previous = new KeyValuePair<int, int>(); 

      foreach (var current in d1) 
      { 
       if (!isFirst) 
       { 
        // You have current and previous available now. 
        Console.WriteLine("Current = " + current.Value + ", previous = " + previous.Value); 
       } 

       previous = current; 
       isFirst = false; 
      } 
     } 
    } 
} 

А вот как вы можете сделать это вручную с помощью нумератор:

using System; 
    using System.Collections.Generic; 

    namespace Demo 
    { 
     public static class Program 
     { 
      private static void Main(string[] args) 
      { 
       var d1 = new Dictionary<int, int> {{1, 1}, {2, 2}, {3, 3}, {4, 4}}; 
       var iter = d1.GetEnumerator(); 

       if (iter.MoveNext()) 
       { 
        var previous = iter.Current; 

        while (iter.MoveNext()) 
        { 
         // You have current and previous available now. 
         Console.WriteLine("Current = " + iter.Current.Value + ", previous = " + previous.Value); 
         previous = iter.Current; 
        } 
       } 
      } 
     } 
    } 
0

Зачем вам нужен итератор? Цикл foreach сделает это для вас.

Если вам нужен текущий и предыдущий пункт, вы можете просто сохранить предыдущий элемент в каждой итерации:

Dictionary<int, int> d1 = new Dictionary<int, int>(); 
KeyValuePair<int, int> previous = null; 
KeyValuePair<int, int> current = null; 
foreach (KeyValuePair<int, int> item in d1) 
{ 
    previous = current; 
    current = item; 
    // do what you need to do with previous and current 
} 

Вы можете также использовать SortedDictionary, который даст вам индекс.

+0

Используя неинициализированное значение ... –

+0

Исправить. Если null, у вас нет предыдущего элемента. – gabnaim

+0

Я отредактировал ответ на intialize to null. – gabnaim

2

Похоже, вы хотите иметь доступ к предыдущему значению, а также к текущему значению последовательности. Вот простой вспомогательный метод, который принимает последовательность и превращает его в последовательность пара, который представляет каждое значение с его предыдущим значением в исходной последовательности:

public static IEnumerable<Tuple<T, T>> GroupAdjacent<T>(IEnumerable<T> source) 
{ 
    using (var iterator = source.GetEnumerator()) 
    { 
     if (!iterator.MoveNext()) 
     { 
      yield break; 
     } 
     T previous = iterator.Current; 

     while (iterator.MoveNext()) 
     { 
      yield return Tuple.Create(previous, iterator.Current); 
     } 
    } 
} 

Затем он может быть использован как:

foreach(var pair in GroupAdjacent(dictionary)) 
{ 
    var previous = pair.Item1; 
    var current = pair.Item2; 
} 
0
List<KeyValuePair<Int32, Int32>> keyValuePairsWithIterations = new List<KeyValuePair<Int32, Int32>>(); 

foreach(var keyvaluepair in d1) 
{ 
    keyValuePairsWithIterations.Add(keyvaluepair); 
} 

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

Смежные вопросы