Hogyan rendezni a szótárba érték?

szavazat
671

Gyakran kell rendezni egy szótár, amely a kulcsok és értékek, az érték. Például, van egy hash szavak és a frekvenciákat, hogy szeretnék rendelni gyakoriság.

Van egy SortedList, ami jó egy értéket (mondjuk frekvencia), hogy szeretnék feltérképezni vissza a szót.

SortedDictionary megrendelések kulcs, nem érték. Néhány üdülőhelyen egy egyéni osztályt , de van egy tisztább út?

A kérdést 02/08/2008 01:40
a forrás felhasználó
Más nyelveken...                            


17 válasz

szavazat
473

Használja LINQ:

Dictionary<string, int> myDict = new Dictionary<string, int>();
myDict.Add("one", 1);
myDict.Add("four", 4);
myDict.Add("two", 2);
myDict.Add("three", 3);

var sortedDict = from entry in myDict orderby entry.Value ascending select entry;

Ez lehetővé tenné, nagy rugalmasságot, hogy válassza ki a legjobb 10, 20 10%, stb Vagy ha használja a szó gyakorisága index type-ahead, akkor is StartsWithzáradékot is.

Válaszolt 04/08/2008 16:22
a forrás felhasználó

szavazat
459

Használat:

using System.Linq.Enumerable;
...
List<KeyValuePair<string, string>> myList = aDictionary.ToList();

myList.Sort(
    delegate(KeyValuePair<string, string> pair1,
    KeyValuePair<string, string> pair2)
    {
        return pair1.Value.CompareTo(pair2.Value);
    }
);

Mivel céloz .NET 2.0 vagy újabb, akkor egyszerűsíteni ezt a lambda szintaxis - ez egyenértékű, de rövidebb. Ha céloz .NET 2.0 csak akkor lehet használni ezt a szintaxist, ha használja a fordító a Visual Studio 2008 (vagy újabb).

var myList = aDictionary.ToList();

myList.Sort((pair1,pair2) => pair1.Value.CompareTo(pair2.Value));
Válaszolt 02/08/2008 02:15
a forrás felhasználó

szavazat
179
var ordered = dict.OrderBy(x => x.Value);
Válaszolt 11/11/2010 18:16
a forrás felhasználó

szavazat
148

Körülnézett, és segítségével néhány C # 3.0 funkciókat tudjuk ezt:

foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value))
{ 
    // do something with item.Key and item.Value
}

Ez a legtisztább út láttam, és hasonló a Ruby módon kezeli hash-eket.

Válaszolt 02/08/2008 01:43
a forrás felhasználó

szavazat
140

Tudod rendezni a szótár érték szerint, és mentse vissza önmagába (úgy, hogy ha foreach rajta az értékek jönnek ki sorrendben):

dict = dict.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);

Persze, ez nem lehet helyes, de működik.

Válaszolt 22/06/2011 11:26
a forrás felhasználó

szavazat
56

A magas szintű, akkor nincs más választása, majd a séta az egész szótár és nézd meg minden értéket.

Talán ez segít: http://bytes.com/forum/thread563638.html Copy / beillesztése: John Timney:

Dictionary<string, string> s = new Dictionary<string, string>();
s.Add("1", "a Item");
s.Add("2", "c Item");
s.Add("3", "b Item");

List<KeyValuePair<string, string>> myList = new List<KeyValuePair<string, string>>(s);
myList.Sort(
    delegate(KeyValuePair<string, string> firstPair,
    KeyValuePair<string, string> nextPair)
    {
        return firstPair.Value.CompareTo(nextPair.Value);
    }
);
Válaszolt 02/08/2008 01:47
a forrás felhasználó

szavazat
22

Soha nem lesz képes rendezni a szótárban egyébként. Ezek valójában nem rendelhető. A garanciák egy szótár, amely a kulcs és az érték gyűjtemények iterable és értékek lehívhatja index vagy a kulcs, de itt nincs garancia bármely adott sorrendben. Ezért van szüksége lenne, hogy a név-érték párt egy listába.

Válaszolt 19/12/2008 23:47
a forrás felhasználó

szavazat
16

Nem rendezze a bejegyzéseket a szótár. Szótár osztály .NET van megvalósítva hash - ez az adat struktúra nem rendezhető definíció szerint.

Ha kell, hogy képes legyen végighaladni a gyűjtemény (kulccsal) - akkor kell használni SortedDictionary, amely végre a bináris kereső fába.

Az Ön esetében azonban a forrás struktúra nem releváns, mert van rendezve egy másik területen. Azt még meg kell rendezni a frekvencia és betette egy új gyűjtemény sorolva az adott területen (frekvencia). Tehát ebben a gyűjteményben a frekvenciák kulcsok és szavak értékeket. Mivel sok szó nem lehet azonos a frekvencia (és fogsz használni, mint egy kulcs) nem lehet használni sem szótár sem SortedDictionary (általuk igényelt egyedi kulcsokat). Ez hagyja a SortedList.

Nem értem, hogy miért ragaszkodnak fenntartása a linket az eredeti elemet a main / első szótárban.

Ha a tárgyak a gyűjtemény volt bonyolultabb szerkezetű (több mező), és szükséges, hogy képes legyen hatékonyan elérhető / rendezni őket a különböző területeken, mint a kulcsok - Ön valószínűleg szüksége van egy egyedi adat struktúra, amely tartalmazza a fő tároló, amely támogatja O (1) behelyezése és eltávolítása (láncolt lista) és több indexelő struktúrák - Szótár / SortedDictionaries / SortedLists. Ezek az indexek is használja az egyik olyan terület, saját komplex osztályt egy kulcsot és egy mutatót / hivatkozás LinkedListNode a láncolt lista, mint érték.

Azt kell, hogy koordinálja beszúrások és a törlések tartani a indexekkel szinkronban a fő gyűjtemény (láncolt lista) és az abszorpció lenne elég drága én hiszem. Ez hasonló ahhoz, hogyan tárol indexek működnek - ezek fantasztikus kereséseket de terhet, ha kell végezni számos insetions törléseket.

Az összes fenti csak akkor indokolt, ha megy, hogy néhány look-up nehéz feldolgozás. Ha csak a kimeneti őket egyszer gyakoriság szerint válogatva, akkor is csak egy listát a (névtelen) sorok:

var dict = new SortedDictionary<string, int>();
// ToDo: populate dict

var output = dict.OrderBy(e => e.Value).Select(e => new {frequency = e.Value, word = e.Key}).ToList();

foreach (var entry in output)
{
    Console.WriteLine("frequency:{0}, word: {1}",entry.frequency,entry.word);
}
Válaszolt 13/12/2012 07:19
a forrás felhasználó

szavazat
12
Dictionary<string, string> dic= new Dictionary<string, string>();
var ordered = dic.OrderBy(x => x.Value);
return ordered.ToDictionary(t => t.Key, t => t.Value);
Válaszolt 20/07/2015 11:01
a forrás felhasználó

szavazat
10

Rendezés értékek

Ez megmutatja, hogyan kell rendezni az értékek egy szótár. Látjuk a konzol program segítségével összeállítja a Visual Studio és a futás. Hozzáteszi kulcsokat egy szótár, majd rendezi őket az értéküket. Ne feledje, hogy szótár példányok kezdetben nincs rendezve semmilyen módon. Mi használjuk a LINQ orderby kulcsszó a lekérdezés nyilatkozat.

OrderBy szakasz Program, amely rendezi szótár [C #]

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        // Example dictionary.
        var dictionary = new Dictionary<string, int>(5);
        dictionary.Add("cat", 1);
        dictionary.Add("dog", 0);
        dictionary.Add("mouse", 5);
        dictionary.Add("eel", 3);
        dictionary.Add("programmer", 2);

        // Order by values.
        // ... Use LINQ to specify sorting by value.
        var items = from pair in dictionary
                orderby pair.Value ascending
                select pair;

        // Display results.
        foreach (KeyValuePair<string, int> pair in items)
        {
            Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
        }

        // Reverse sort.
        // ... Can be looped over in the same way as above.
        items = from pair in dictionary
        orderby pair.Value descending
        select pair;
    }
}

kibocsátás

dog: 0
cat: 1
programmer: 2
eel: 3
mouse: 5
Válaszolt 20/07/2012 10:49
a forrás felhasználó

szavazat
10

Vagy szórakozásból jól jönne néhány LINQ kiterjesztése jóság:

var dictionary = new Dictionary<string, int> { { "c", 3 }, { "a", 1 }, { "b", 2 } };
dictionary.OrderBy(x => x.Value)
  .ForEach(x => Console.WriteLine("{0}={1}", x.Key,x.Value));
Válaszolt 30/06/2010 12:12
a forrás felhasználó

szavazat
9

Az osztályozás a SortedDictionarylistát, hogy kötődnek egy ListViewvezérlő segítségével VB.NET:

Dim MyDictionary As SortedDictionary(Of String, MyDictionaryEntry)

MyDictionaryListView.ItemsSource = MyDictionary.Values.OrderByDescending(Function(entry) entry.MyValue)

Public Class MyDictionaryEntry ' Need Property for GridViewColumn DisplayMemberBinding
    Public Property MyString As String
    Public Property MyValue As Integer
End Class

XAML:

<ListView Name="MyDictionaryListView">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Path=MyString}" Header="MyStringColumnName"></GridViewColumn>
            <GridViewColumn DisplayMemberBinding="{Binding Path=MyValue}" Header="MyValueColumnName"></GridViewColumn>
         </GridView>
    </ListView.View>
</ListView>
Válaszolt 23/04/2010 10:36
a forrás felhasználó

szavazat
5

Az egyéb válaszok jók, ha minden, amit akarsz, hogy egy „átmeneti” rendezett lista érték. Azonban, ha azt akarjuk, hogy a szótár szerint rendezve Key, hogy automatikusan szinkronizálja egy másik szótárban szerint sorba rendezett Value, jól jönne a Bijection<K1, K2>class .

Bijection<K1, K2> lehetővé teszi, hogy inicializálja a gyűjtemény két meglévő szótárak, így ha azt szeretné, hogy őket, hogy nem válogatott, és azt szeretné, a másikat ki kell válogatni, akkor hozza létre a bijekciót kóddal, mint

var dict = new Bijection<Key, Value>(new Dictionary<Key,Value>(), 
                               new SortedDictionary<Value,Key>());

Használhatja dict, mint bármely másik szótárban (valósítja meg IDictionary<>), majd hívja dict.Inverse, hogy a „fordított” szótár, amely szerint van rendezve Value.

Bijection<K1, K2>része Loyc.Collections.dll , de ha akarod, akkor egyszerűen másolja a forráskódot a saját projekt.

Megjegyzés : Abban az esetben van több kulcsot az azonos értékű, akkor nem tudja használni Bijection, de lehet manuálisan szinkronizálni a közönséges Dictionary<Key,Value>és a BMultiMap<Value,Key>.

Válaszolt 26/02/2016 07:15
a forrás felhasználó

szavazat
5

A legegyszerűbb módja, hogy a rendezett szótár használata a beépített SortedDictionaryosztály:

//Sorts sections according to the key value stored on "sections" unsorted dictionary, which is passed as a constructor argument
System.Collections.Generic.SortedDictionary<int, string> sortedSections = null;
if (sections != null)
{
    sortedSections = new SortedDictionary<int, string>(sections);
}

sortedSections akarat tartalmazza a rendezett változata sections

Válaszolt 02/04/2010 23:36
a forrás felhasználó

szavazat
4

Tegyük fel, hogy van egy szótárban, mint

   Dictionary<int, int> dict = new Dictionary<int, int>();
   dict.Add(21,1041);
   dict.Add(213, 1021);
   dict.Add(45, 1081);
   dict.Add(54, 1091);
   dict.Add(3425, 1061);
   sict.Add(768, 1011);

1), akkor temporary dictionary to store values as:

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

        foreach (KeyValuePair<int, int> pair in dict.OrderBy(key => key.Value))
        {
            dctTemp .Add(pair.Key, pair.Value);
        }
Válaszolt 02/02/2015 10:46
a forrás felhasználó

szavazat
-2

Tekintettel arra, hogy van egy szótárt is lehet rendezni őket közvetlenül értékek segítségével az alábbiakban egy óceánjáró:

var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);
Válaszolt 31/05/2014 23:30
a forrás felhasználó

szavazat
-2

A rendezés Dictionary értékét és az eredményt kapjuk szótárban az alábbi kódot:

Dictionary <<string, string>> ShareUserNewCopy = 
       ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
                                                        pair => pair.Value);                                          
Válaszolt 24/07/2012 13:24
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more