2009-07-22 6 views
25

Jaki jest najlepszy sposób ustawienia wszystkich wartości w słowniku C#?Jaki jest najlepszy sposób ustawienia wszystkich wartości w słowniku C# <string,bool>?

Oto, co robię teraz, ale jestem pewien, że jest lepiej/czystsze sposobem, aby to zrobić:

Dictionary<string,bool> dict = GetDictionary(); 
var keys = dict.Keys.ToList(); 
for (int i = 0; i < keys.Count; i++) 
{ 
    dict[keys[i]] = false; 
} 

Próbowałem kilka innych sposobów, z foreach, ale miałem błędów.

+0

Kolejne pytanie od moje nowe dni :) –

Odpowiedz

60

To rozsądne podejście, chociaż wolałbym:

foreach (var key in dict.Keys.ToList()) 
{ 
    dict[key] = false; 
} 

Wezwanie do ToList() czyni tę pracę, ponieważ jest wyciągając i (chwilowo) zapisując listę kluczy, więc prace iteracji.

+1

Patrząc na mój oryginalny kod, nie wiem, dlaczego nie próbowałem tego. –

+2

dict.Keys.ForEach (k => dict [k] = false); – obenda

+0

@obenda [ForEach considered harmfil] (https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/). –

-2

Można po prostu wyciągnąć ToList() i iteracji bezpośrednio nad słownikowych pozycji

Dictionary<string, bool> dict = GetDictionary(); 
foreach (var pair in dict) 
{ 
    dict[pair.Key] = false; 
} 
+3

Zmiana słownika unieważnia moduł wyliczający i dalsze używanie go spowoduje zgłoszenie wyjątku "InvalidOperationException". –

-4

zrobić to sposób masz go teraz ... foreach jest powolny. Foreach może być czystszy, ale za dużo wykorzystujesz działanie wydajności.

Edit:
http://www.codeproject.com/KB/cs/foreach.aspx
http://www.madprops.org/blog/for-vs-foreach-performance/

+1

W jaki sposób powolne jest "foreach"? –

+0

Patrz wyżej. Przepraszamy za brak dowodów w oryginalnym wpisie. – Polaris878

+0

Metoda "foreach" wymieniona w pierwszym poście * jest * wolna ... do manipulowania istniejącymi wewnętrznymi zasobnikami słownika. –

5

Jeśli nie używasz bools Tri-State, a następnie można użyć HashSet<string> i wywołać Clear() ustawić wartości "false".

+0

To jest dobra alternatywa. –

+0

Nie używam tri-state bools, ale nie rozumiem, jak wdrożyć to, o czym mówisz. Wygląda jednak świetnie! –

+1

@Billy: Jeśli łańcuch jest w 'HashSet', to jest to prawda. Jeśli nie znajduje się w 'HashSet', jest to fałsz. Użyj opcji Dodaj/Usuń zamiast ustawiania wartości true/false. To będzie * bardzo * szybko, ale nie ma sposobu na przedstawienie trzeciego "brakującego" stanu. –

2

Zaprezentowałem różnicę między rozwiązaniami Billy'ego i Reeda. Polaris878, zwróć uwagę na wyniki i pamiętaj, że przedwczesna optymalizacja jest źródłem wszelkiego zła ;-)

Przerobiłem rozwiązania w VB (ponieważ obecnie programuję w tym języku) i użyłem klawiszy int (dla uproszczenia), w przeciwnym razie jest to dokładnie ten sam kod. Uruchomiłem kod ze słownikiem 10 milionów wpisów o wartości "true" dla każdego wpisu. oryginalne rozwiązanie

Billy Szaman za:

Dim keys = dict.Keys.ToList 
For i = 0 To keys.Count - 1 
    dict(keys(i)) = False 
Next 

Upłynęło milisekund: 415

Reed Copsey za rozwiązanie:

For Each key In dict.Keys.ToList 
    dict(key) = False 
Next 

Upłynęło milisekund: 395

Więc w tym przypadku foreach jest rzeczywiście szybsza.

18

Roztwór jeden wiersz:

dict = dict.ToDictionary(p => p.Key, p => false); 
3

Nie jestem pewien, czy to jest najlepszy sposób, ale szukałem czegoś w jednej linii, a ten pracował dla mnie

mydict.Keys.ToList().ForEach(k => mydict[k] = false);