Pergunta

Digamos que eu tenha um objeto de dicionário:

Dictionary myDictionary<int, SomeObject> = new Dictionary<string, SomeObject>();

Agora eu quero iterar através do dicionário em ordem inversa. Não posso usar um loop simples porque não conheço as chaves do dicionário. UMA para cada é fácil:

foreach (SomeObject object in myDictionary.Values)
{
    // Do stuff to object
}

Mas como posso executar isso ao contrário?

Foi útil?

Solução

Eu usaria uma lista classificada em vez de um dicionário. Você ainda pode acessá -lo por chave, mas também pode acessá -lo por índice.

SortedList sCol = new SortedList();

sCol.Add("bee", "Some extended string matching bee");
sCol.Add("ay", "value matching ay");
sCol.Add("cee", "Just a standard cee");

// Go through it backwards.
for (int i = sCol.Count - 1; i >=0 ; i--)
    Console.WriteLine("sCol[" + i.ToString() + "] = " + sCol.GetByIndex(i));

// Reference By Key
foreach (string i in sCol.Keys)
    Console.WriteLine("sCol[" + i + "] = " + sCol[i]);

// Enumerate all values
foreach (string i in sCol.Values)
    Console.WriteLine(i);

Vale a pena notar que uma lista classificada armazena pares de chave/valor classificados apenas por chave.

Outras dicas

Um dicionário ou qualquer outra forma de hashtable não tem pedido. Então, o que você está tentando fazer é inútil :)

Se você possui .NET 3.5, você pode usar o método de extensão .versever () em iEnumerables. Por exemplo:

foeach (SomeObject o in myDictionary.Values.Reverse())
{
     // Do stuff to object
}

Na verdade, no C# 2.0, você pode criar seu próprio iterador que atravessa um contêiner ao contrário. Em seguida, você pode usar esse iterador na sua declaração foreach. Mas seu iterador teria que ter uma maneira de navegar no contêiner em primeiro lugar. Se for uma matriz simples, pode voltar para trás assim:

static IEnumerable<T> CreateReverseIterator<T>(IList<T> list)
{
    int count = list.Count;
    for (int i = count - 1; i >= 0; --i)
    {
        yield return list[i];
    }
}

Mas é claro que você não pode fazer isso com um dicionário, pois ele não implementa o ILIST ou fornece um indexador. Dizer que um dicionário não tem ordem não é verdadeiro: é claro que tem ordem. Esse pedido pode até ser útil se você souber o que é.

Para uma solução para o seu problema: eu diria que copie os elementos para uma matriz e use o método acima para atravessá -lo ao contrário. Assim:

static void Main(string[] args)
{
    Dictionary<int, string> dict = new Dictionary<int, string>();

    dict[1] = "value1";
    dict[2] = "value2";
    dict[3] = "value3";

    foreach (KeyValuePair<int, string> item in dict)
    {
        Console.WriteLine("Key : {0}, Value: {1}", new object[] { item.Key, item.Value });
    }

    string[] values = new string[dict.Values.Count];
    dict.Values.CopyTo(values, 0);

    foreach (string value in CreateReverseIterator(values))
    {
        Console.WriteLine("Value: {0}", value);
    }

}

Copiar seus valores para uma matriz pode parecer uma má idéia, mas, dependendo do tipo de valor, não é realmente tão ruim assim. Você pode estar apenas copiando referências!

Eu concordo com @Leppie, mas acho que você merece uma resposta para a pergunta em geral. Pode ser que você quisesse que a pergunta fosse em geral, mas acidentalmente escolheu uma estrutura de dados ruim. A ordem dos valores em um dicionário deve ser considerada específica da implementação; De acordo com a documentação, é sempre a mesma ordem que as chaves, mas essa ordem também não é especificada.

Enfim, não há uma maneira direta de fazer foreach Trabalhe ao contrário. É açúcar sintático para usar o enumerador da classe, e os enumeradores só podem viajar em uma direção. Tecnicamente, a resposta pode ser "reverter a coleção e depois enumerar", mas acho que este é um caso em que você só terá que usar um "para trás" para o loop:

for (int i = myCollection.Length - 1; i >= 0; i--)
{
    // do something
}

Se você não possui .NET 3.5 e, portanto, o método de extensão reversa, você pode implementar o seu. Eu acho que provavelmente gera uma lista intermediária (quando necessário) e a itera ao contrário, algo como o seguinte:

public static IEnumerable<T> Reverse<T>(IEnumerable<T> items)
{
    IList<T> list = items as IList<T>;
    if (list == null) list = new List<T>(items);
    for (int i = list.Count - 1; i >= 0; i-- )
    {
        yield return list[i];
    }
}

Isso seria um Dictionary<int, SomeObject> myDictionary, e você faria isso por:

foreach(SomeObject _object in myDictionary.Values.Reverse())
{
}

A única maneira de encontrar em .NET 2.0 é primeiro copiar todos os valores para uma lista, reverter a lista e depois executar o foreach nessa lista:

Dictionary<int, object> d;
List<object> tmplist;
foreach (object o in d.Values) tmplist.Add(s);
tmplist.Reverse();
foreach (object o in tmplist) {
    //Do stuff
}

Se o pedido for mais importante, você poderá uma pilha e criar uma estrutura simples para armazenar seu par de objetos int,.

Se você deseja uma coleção de tipos de dicionário, mas precisa manter a ordem de inserção, pode olhar para a coleta de keyedcollectionaqui

É uma fusão entre um dicionário e uma lista. Dessa forma, você pode acessar elementos na coleção através da chave ou do índice de inserção.

O único Gotcha é se o seu elemento que está sendo armazenado na coleção precisará ter uma tecla int. Se você pudesse alterar isso para uma string ou outro tipo (Guid Mabye). Desde coleção1 estará procurando a chave de 1 e não o índice de 1.

Um padrão for Loop seria o melhor. Você não precisa se preocupar com a sobrecarga de processamento de reverter a coleção.

Você pode usar o Linq para objetos Enumerable.Reverse () Função no .NET 2.0 usando Linqbridge.

Resposta literal:

Dictionary<int, SomeObject>  myDictionary = new Dictionary<int, SomeObject>();

foreach (var pair in myDictionary.OrderByDescending(i => i.Key))
{
    //Observe pair.Key
    //Do stuff to pair.Value
}
foreach (Sample in Samples)

try the following:

Int32 nEndingSample = Samples.Count - 1;

for (i = nEndingSample; i >= 0; i--)
{
     x = Samples[i].x;
     y = Samples[i].y;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top