Answer-ID
  • Întrebări
  • Tag-uri
  • Categorii
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
Michael Stum
Michael Stum

Accesarea unui Dicționar.Cheile Cheii printr-un index numeric

Am'm, folosind un Dicționar<string, int>undeint` este un număr de cheie.

Acum, am nevoie pentru a accesa ultimul introdus Cheia în Dicționar, dar nu stiu numele. Evident încercare:

nu funcționează, pentru că în Dicționarul.Tastele nu pune în aplicare o []-indexer.

Mă întreb dacă nu există nici o clasă similară? M-am gândit folosind o Stivă, dar asta doar memorează un șir de caractere. Am putea crea acum propriile mele struct și de a folosi apoi un Teanc, dar mă întreb dacă nu există o altă alternativă, în esență, un Dicționar care implementează un []-indexer pe Taste?

152 2008-08-07T00:51:21+00:00 15
Programare
.net
c#
dictionary
Comentarii la întrebare (1)
Soluția
Vitor Hugo
Vitor Hugo
19 ianuarie 2011 в 1:21
2011-01-19T13:21:27+00:00
Mai mult
Sursă
Editează
#8409578

Ca @Falanwe puncte într-un comentariu, face ceva de genul asta este incorectă:

Ai nu trebuie depinde de ordinea de chei într-un Dicționar. Dacă aveți nevoie de a comanda, ar trebui să utilizați un OrderedDictionary, așa cum este propusă în răspunde. Alte răspunsuri pe această pagină sunt interesante, la fel de bine.

214
0
Comentarii (7)
Andrew Peters
Andrew Peters
8 august 2008 в 1:23
2008-08-08T01:23:22+00:00
Mai mult
Sursă
Editează
#8409575

Puteți utiliza un OrderedDictionary.

Reprezintă o colecție de cheie/valoare perechi care sunt accesibile prin cheia sau index.

57
0
Comentarii (2)
Utilizator anonim
16 aprilie 2009 в 2:09
2009-04-16T14:09:29+00:00
Mai mult
Sursă
Editează
#8409576

Un Dicționar este un Tabel Hash, astfel încât aveți nici o idee despre ordinul de inserție!

Dacă vrei să știi, ultimul introdus cheia aș sugera extinderea Dicționar pentru a include un LastKeyInserted valoare.

E. g.:

{
    private IDictionary<K, T> _InnerDictionary;

    public K LastInsertedKey { get; set; }

    public MyDictionary()
    {
        _InnerDictionary = new Dictionary<K, T>();
    }

    #region Implementation of IDictionary

    public void Add(KeyValuePair<K, T> item)
    {
        _InnerDictionary.Add(item);
        LastInsertedKey = item.Key;

    }

    public void Add(K key, T value)
    {
        _InnerDictionary.Add(key, value);
        LastInsertedKey = key;
    }

    .... rest of IDictionary methods

    #endregion

}

Va rula în probleme cu toate acestea, atunci când utilizați .Elimina() deci, pentru a depăși acest lucru, va trebui să păstreze o listă ordonată de cheile introdus.

17
0
Comentarii (0)
 Calanus
Calanus
7 august 2008 в 11:15
2008-08-07T11:15:35+00:00
Mai mult
Sursă
Editează
#8409574

De ce nu't ai prelungi dicționar class pentru a adăuga într-un ultim cheie introdus de proprietate. Ceva de genul următor poate?

{
    private int lastKeyInserted = -1;

    public int LastKeyInserted
    {
        get { return lastKeyInserted; }
        set { lastKeyInserted = value; }
    }

    public void AddNew(string s, int i)
    {
        lastKeyInserted = i;

        base.Add(s, i);
    }
}
8
0
Comentarii (2)
 Patrick
Patrick
7 august 2008 в 1:13
2008-08-07T01:13:22+00:00
Mai mult
Sursă
Editează
#8409569

Ai putea întotdeauna face acest lucru:

mydict.Keys.CopyTo(temp, 0)
int LastCount = mydict[temp[mydict.count - 1]]

Dar nu't recomanda. Nu's nici o garanție că ultima introdus cheia va fi la sfârșitul șirului. Comanda pentru Chei pe MSDN este nespecificat, și sub rezerva de a schimba. În foarte scurt test, aceasta nu pare să fie în ordine de inserție, dar'd fi mai bine clădire corespunzătoare în contabilitate ca o stivă-cum ai sugerat (deși nu - 't vedea nevoie de un struct, bazate pe alte declarații)--sau singură variabilă cache-ul dacă aveți nevoie doar să știu de cele mai recente cheie.

6
0
Comentarii (0)
 Juan
Juan
7 august 2008 в 1:18
2008-08-07T01:18:25+00:00
Mai mult
Sursă
Editează
#8409571

Cred că puteți face ceva de genul asta, sintaxa ar putea fi greșit, n-a folosit C# într-un timp Pentru a ajunge la ultimul element

string lastKey = keys.Last();

sau de a folosi Max în loc de Trecut pentru a ajunge la valoarea maximă, nu stiu care se potriveste codul mai bine.

5
0
Comentarii (2)
Daniel Ballinger
Daniel Ballinger
20 iulie 2011 в 12:45
2011-07-20T00:45:48+00:00
Mai mult
Sursă
Editează
#8409579

O alternativă ar fi un KeyedCollection în cazul în care cheia este încorporat în valoare.

Doar a crea o bază de implementare a sigilat într-o clasă de a utiliza.

Deci, pentru a înlocui în Dicționarul<string, int> (care nu e't un foarte bun exemplu ca nu e't o cheie de clar pentru un int).

{
    protected override string GetKeyForItem(int item)
    {
        // The example works better when the value contains the key. It falls down a bit for a dictionary of ints.
        return item.ToString();
    }
}

KeyedCollection<string, int> intCollection = new ClassThatContainsSealedImplementation.IntDictionary();

intCollection.Add(7);

int valueByIndex = intCollection[0];
4
0
Comentarii (1)
Stephen Pellicer
Stephen Pellicer
7 august 2008 в 2:38
2008-08-07T02:38:29+00:00
Mai mult
Sursă
Editează
#8409572

Sunt de acord cu partea a doua de Patrick's a răspunde. Chiar dacă în unele teste se pare a ține de inserție comandă, documentația (și un comportament normal pentru dicționare și hash-uri) în mod explicit în comanda este nespecificat.

Te're lumânarea în funcție de comanda de chei. Adăugați propriile contabilitate (ca Patrick mi-a spus, doar o singură variabilă pentru ultima adăugat cheie) pentru a fi sigur. De asemenea, don't fi tentat de toate metodele cum ar fi Ultima și Max în dicționar ca acestea sunt, probabil, în ceea ce privește cheia de comparator (I'm nu sunt sigur de asta).

4
0
Comentarii (0)
Glenn Slayden
Glenn Slayden
12 aprilie 2010 в 4:44
2010-04-12T04:44:58+00:00
Mai mult
Sursă
Editează
#8409577

În cazul în care vă decideți să utilizați cod periculos, care este obiectul la rupere, această funcție de extensie va aduce o cheie de la un `Dicționar<K,V> potrivit spuselor sale interne de indexare (care pentru Mono și .NET în prezent pare să fie în aceeași ordine ca ai obține prin enumerarea "Cheilor" de proprietate).

Este de preferat a folosi Linq: dict.Tastele.ElementAt(i), dar că funcția se va repeta O(N); următoarele este O(1), dar cu o reflecție penalizare de performanță.

using System.Collections.Generic;
using System.Reflection;

public static class Extensions
{
    public static TKey KeyByIndex<TKey,TValue>(this Dictionary<TKey, TValue> dict, int idx)
    {
        Type type = typeof(Dictionary<TKey, TValue>);
        FieldInfo info = type.GetField("entries", BindingFlags.NonPublic | BindingFlags.Instance);
        if (info != null)
        {
            // .NET
            Object element = ((Array)info.GetValue(dict)).GetValue(idx);
            return (TKey)element.GetType().GetField("key", BindingFlags.Public | BindingFlags.Instance).GetValue(element);
        }
        // Mono:
        info = type.GetField("keySlots", BindingFlags.NonPublic | BindingFlags.Instance);
        return (TKey)((Array)info.GetValue(dict)).GetValue(idx);
    }
};
4
0
Comentarii (1)
Jeremy Privett
Jeremy Privett
7 august 2008 в 2:40
2008-08-07T02:40:52+00:00
Mai mult
Sursă
Editează
#8409573

Felul în care ai formulat întrebarea mă face să cred că int în Dicționarul conține elementul's "poziția" în Dicționar. Judecând după afirmația că tastele sunt't stocate în ordinea în care au're adăugată, dacă aceasta este corectă, ar însemna că cheile.Count (sau .Count - 1, daca're folosind zero-based) ar trebui totuși să fie întotdeauna numărul de ultimul-intrat-cheie?

Dacă asta's corecte, nu există nici un motiv să puteți't folosi în loc de Dicționar<int, string> astfel încât să puteți utiliza mydict[ mydict.Tastele.Conta ]?

3
0
Comentarii (0)
 lomaxx
lomaxx
7 august 2008 в 1:15
2008-08-07T01:15:55+00:00
Mai mult
Sursă
Editează
#8409570

Eu nu't știu dacă acest lucru ar funcționa pentru că m-am'm destul de sigur că tastele sunt't stocate în ordinea în care acestea sunt adăugate, dar ai putea arunca KeysCollection la o Listă și apoi a obține ultima cheie din lista... dar ar fi în valoare de o privire.

Singurul lucru la care mă pot gândi este de a stoca cheile într-o listă de căutare și se adaugă cheile de la lista înainte de a le adăuga la dicționar... l's nu destul tho.

2
0
Comentarii (3)
 takrl
takrl
20 iulie 2011 в 9:21
2011-07-20T09:21:45+00:00
Mai mult
Sursă
Editează
#8409580

Pentru a extinde pe Daniels post și comentarii cu privire la cheie, din moment ce cheia este încorporat în valoarea oricum, ai putea recurge la utilizarea unui KeyValuePair<TKey, TValue>` ca valoare. Principalul argument pentru aceasta este faptul că, în general, Cheia e't neapărat direct decurg din valoare.

Apoi se'd arata astfel:

  : KeyedCollection<TKey, KeyValuePair<TKey, TValue>>
{
  protected override TKey GetKeyForItem(KeyValuePair<TKey, TValue> item)
  {
    return item.Key;
  }
}

Pentru a folosi acest lucru ca în exemplul anterior, ar'd face:


custDict.Add(new KeyValuePair<string, int>("key", 7));

int valueByIndex = custDict[0].Value;
int valueByKey = custDict["key"].Value;
string keyByIndex = custDict[0].Key;
2
0
Comentarii (0)
Sharunas Bielskis
Sharunas Bielskis
25 martie 2015 в 6:13
2015-03-25T18:13:00+00:00
Mai mult
Sursă
Editează
#8409581

Puteți folosi, de asemenea, Motorola și omologul său Generic. Aceste două clase și în Andrew Peters răspunsul menționat OrderedDictionary dicționar sunt clase în care elementele pot fi accesate prin index (pozitie), precum și de cheie. Cum să utilizați aceste cursuri puteți găsi: Motorola Clasa , Motorola Clasă Generică .

2
0
Comentarii (0)
 espaciomore
espaciomore
6 aprilie 2016 в 9:15
2016-04-06T21:15:54+00:00
Mai mult
Sursă
Editează
#8409582

Un dicționar nu poate fi foarte intuitiv pentru utilizarea indicelui de referință, dar, puteți avea operațiuni similare cu o serie de KeyValuePair:

ex. KeyValuePair<string, string>[] filtre;

2
0
Comentarii (0)
 quicktrick
quicktrick
3 noiembrie 2016 в 8:42
2016-11-03T08:42:21+00:00
Mai mult
Sursă
Editează
#8409583

Visual Studio's UserVoice dă un link la generic OrderedDictionary implementation de dotmore.

Dar dacă aveți nevoie doar pentru a obține perechi cheie/valoare de index și don't nevoie pentru a obține valorile de taste, puteți folosi un truc simplu. Declara unele clasă generică (l-am numit ListArray), după cum urmează:

Puteți, de asemenea, să declare, cu constructori:

{
    public ListArray() : base() { }
    public ListArray(int capacity) : base(capacity) { }
}

De exemplu, ai citit unele perechi cheie/valoare dintr-un fișier și doriți doar pentru a le stoca în ordinea în care au fost citite astfel încât pentru a obține-le mai târziu de index:

using (var sr = new StreamReader(myFile))
{
    string line;
    while ((line = sr.ReadLine()) != null)
    {
        string[] keyValueStrings = line.Split(separator);
        for (int i = 0; i < keyValueStrings.Length; i++)
            keyValueStrings[i] = keyValueStrings[i].Trim();
        settingsRead.Add(keyValueStrings);
    }
}
// Later you get your key/value strings simply by index
string[] myKeyValueStrings = settingsRead[index];

Așa cum poate ați observat, puteți avea nu neapărat doar de perechi cheie/valoare în ListArray. Elementul de matrice poate fi de orice lungime, ca în zimțate matrice.

1
0
Comentarii (0)
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
ID
KO
RO
RU
© Answer-ID 2021
Sursă
https://stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire