C # sözünün üzərində yineleme üçün ən yaxşı yol nədir?

C # sözünün üzərində bir neçə fərqli yolları təkrarladıq. Standart bir yol varmı?

1677
26 сент. Jake Stewart tərəfindən təyin olunan 26 sentyabr. 2008-09-26 21:20 '08 at 21:20 pm 2008-09-26 21:20
@ 20 cavab
2547
26 сент. cavab 26 sentyabrda Pablo Fernandes tərəfindən verilir . 2008-09-26 21:22 '08 at 9:22 pm 2008-09-26 21:22

C # -də ümumi bir lüğət istifadə etməyə çalışırsınızsa, sanki başqa bir dildə birləşmə array istifadə edirsinizsə:

 foreach(var item in myDictionary) { foo(item.Key); bar(item.Value); } 

Və ya, yalnız əsas kolleksiyadan keçmək lazımdırsa, istifadə edin

 foreach(var item in myDictionary.Keys) { foo(item); } 
border=0

Və nəhayət, yalnız dəyərlər ilə maraqlanırsınızsa:

 foreach(var item in myDictionary.Values) { foo(item); } 

(Xahiş edirik ki, var sözü, C # 3.0 və yuxarıdakı isteğe bağlı bir funksiyadır, burada da açarlarınızın / dəyərlərinizin tam növü istifadə edə bilərsiniz)

528
26 сент. Cavab Yaqub tərəfindən 26 sentyabrda verilir. 2008-09-26 21:22 '08 at 9:22 pm 2008-09-26 21:22

Bəzi hallarda, döngəni tətbiq etmək üçün təmin edilə biləcək sayğac tələb edə bilər. Bunun üçün, LINQ aşağıdakılara imkan verən ElementAt təmin edir:

 for (int index = 0; index < dictionary.Count; index++) { var item = dictionary.ElementAt(index); var itemKey = item.Key; var itemValue = item.Value; } 
98
10 марта '11 в 23:44 2011-03-10 23:44 Cavab Maurisio Fedatto tərəfindən 10 Mart 2011 tarixində saat 23:44 'də veriləcək 2011-03-10 23:44

Tuşlar və ya dəyərlər arxasında olub-olmadığından asılı olaraq ...

MSDN Dictionary <(Of <(TKey, TValue>)>) Təsviri:

 // When you use foreach to enumerate dictionary elements, // the elements are retrieved as KeyValuePair objects. Console.WriteLine(); foreach( KeyValuePair<string, string> kvp in openWith ) { Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value); } // To get the values alone, use the Values property. Dictionary<string, string>.ValueCollection valueColl = openWith.Values; // The elements of the ValueCollection are strongly typed // with the type that was specified for dictionary values. Console.WriteLine(); foreach( string s in valueColl ) { Console.WriteLine("Value = {0}", s); } // To get the keys alone, use the Keys property. Dictionary<string, string>.KeyCollection keyColl = openWith.Keys; // The elements of the KeyCollection are strongly typed // with the type that was specified for dictionary keys. Console.WriteLine(); foreach( string s in keyColl ) { Console.WriteLine("Key = {0}", s); } 
71
26 сент. cavab J Healy tərəfindən 26 sentyabrda verilir. 2008-09-26 21:27 '08 at 9:27 pm 2008-09-26 21:27

Bir qayda olaraq, müəyyən bir kontekst olmadan "yaxşı yol" tələbi ən yaxşı rəng nədir.

Bir tərəfdən çox rəng var və daha yaxşı bir rəng yoxdur. Bu ehtiyacdan və tez-tez daddan asılıdır.

Digər tərəfdən, C #-də bir lüğət üzərində yineleme üçün bir çox yol var və daha yaxşı bir yol yoxdur. Bu ehtiyacdan və tez-tez daddan asılıdır.

Ən asan yol

 foreach (var kvp in items) { // key is kvp.Key doStuff(kvp.Value) } 

Yalnız bir dəyərə ehtiyacınız varsa ( kvp.Value daha çox oxunaqlıdır).

 foreach (var item in items.Values) { doStuff(item) } 

Müəyyən bir sıralama sifarişinə ehtiyacınız varsa

Bir qayda olaraq, yeni başlayanlar lüğət siyahısının sırasına görə təəccüblənirlər.

LINQ bir sifariş (və daha çox) müəyyən etməyə imkan verən qısa bir sintaksis təmin edir, məsələn:

 foreach (var kvp in items.OrderBy(kvp => kvp.Key)) { // key is kvp.Key doStuff(kvp.Value) } 

Yenə də yalnız dəyərə ehtiyacınız ola bilər. LINQ ayrıca qısa bir həll təqdim edir:

  • birbaşa dəyərdə təkrarlanma ( kvp.Value dən daha çox oxunaqlıdır)
  • lakin açarları ilə sıralanır

Burada:

 foreach (var item in items.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value)) { doStuff(item) } 

Bu nümunələrdə real dünyada istifadə nümunələri çoxdur. Müəyyən bir sifarişə ehtiyacınız yoxdursa, yalnız "ən asan yol" (yuxarıya baxın!)

48
10 авг. Stefan Gourichon tərəfindən verilmiş cavab 10 Avqust. 2015-08-10 14:15 '15 'da 14:15' de 2015-08-10 14:15

Mən dedim ki, foreach standart yoludur, baxmayaraq ki, sizin aradığınız şeydən asılıdır.

 foreach(var value in my_dictionary) { ... } 

Aradığınız bu nədir?

30
26 сент. Cavab George Mauer tərəfindən verilir 26 sep. 2008-09-26 21:22 '08 at 9:22 pm 2008-09-26 21:22

Bir çox variant var. Mənim şəxsi favorim KeyValuePairdir

 Dictionary<string,object> myDictionary = new Dictionary<string,object>(); //Populate your dictionary here Foreach (KeyValuePair<string,object> kvp in myDictionary) { //Do some interesting things; } 

Ayrıca, Açar ve Değer Koleksiyonlarını da istifadə edə bilərsiniz.

21
26 сент. Cavab teo 26 sep tərəfindən verilir . 2008-09-26 21:22 '08 at 9:22 pm 2008-09-26 21:22

Çox yivli emal üçün böyük lüğətlərdə də bunu edə bilərsiniz.

 dictionary .AsParallel() .ForAll(pair => { // Process pair.Key and pair.Value here }); 
19
11 июня '15 в 16:32 2015-06-11 16:32 Cavab Onur 11 iyun '15 'də 16:32' də verilir

Anlayıram ki, bu sual artıq zəngin bir cavab idi, amma bir az araşdırma etmək istəmişdim.

Dictionary iteration bir sıra kimi bir şey üzərində yineleme ilə müqayisədə olduqca yavaş ola bilər. Mənim testlərimdə bir sıra üzərinə yivləmə 0,015003 saniyə çəkdi, bir sözün üzərində (eyni element sayı ilə) təkrarlanarkən 0,0365073 saniyə çəkdi ki, bu da 2,4 dəfə çoxdur! Mən çox böyük fərqlər görmüşəm. Müqayisə üçün Siyahı 0.00215043 saniyə arasındakı bir yerdə idi.

Lakin bu, alma və portağın müqayisəsinə bənzəyir. Sözsüzlüyə görə təkrarlanma yavaş deyirəm.

Sözlüklər axtarış üçün optimallaşdırılmışdır, buna görə də nəzərə alınmaqla iki üsul yaratmışam. Birincisi, foreach, ikincisi düymələri təkrarlayır, sonra baxır.

  public static string Normal(Dictionary<string, string> dictionary) { string value; int count = 0; foreach (var kvp in dictionary) { value = kvp.Value; count++; } return "Normal"; } 

Bu düymələr yüklənir və onları yerinə təkrar edir (mən də düymələri [] xəttinə çəkməyə çalışdım, amma fərq əhəmiyyətsiz idi.

  public static string Keys(Dictionary<string, string> dictionary) { string value; int count = 0; foreach (var key in dictionary.Keys) { value = dictionary[key]; count++; } return "Keys"; } 

Bu nümunədə, adi foreach testi 0.0310062, üst versiyası isə 0.2205441 səviyyəsində idi. Bütün düymələri yükləmək və bütün axtarışları təkrarlamaq daha aydındır!

Son test üçün buradakı düymələri istifadə etməkdə üstünlüklər olub olmadığını (bu mənada yalnız maraqlı olduğumu) öyrənmək üçün mənim iteratı on dəfə yerinə yetirdim:

Bu, nə baş verdiyini başa düşməyiniz üçün RunTest metodundan istifadə edir.

  private static string RunTest<T>(T dictionary, Func<T, string> function) { DateTime start = DateTime.Now; string name = null; for (int i = 0; i < 10; i++) { name = function(dictionary); } DateTime end = DateTime.Now; var duration = end.Subtract(start); return string.Format("{0} took {1} seconds", name, duration.TotalSeconds); } 

Burada, adi foreach qaçışı 0.2820564 saniyə (təxminən bir dəfə təkrarlanma ilə təxminən on dəfə) davam etdi. Tuşlar üzərində təkrarlama 2.2249449 saniyə çəkdi.

Əlavə etmək üçün redaktə: Bir başqa cavab oxuduqdan sonra, mən sözün əvəzinə bir lüğət istifadə edildikdə nə baş verəcəyini soruşdum. Bu nümunədə, dizi 0.0120024 saniyə, 0.0185037 saniyə siyahı və lüğət 0.0465093 saniyə çəkdi. Məlumat növünün lüğətin nə qədər yavaş olacağına təsir etməyini gözləmək məqsədəuyğundur.

Mənim tapıntılarım nədir?

  • Sözün təkrarlanmasından çəkinin, mümkün olduqda, eyni məlumatları olan bir sıra üzərində təkrarlamaqdan əhəmiyyətli dərəcədə yavaş olur.
  • Sözlükdən keçmək istəsəniz, standart foreach metodundan daha səmərəli olmağınıza baxmayaraq, çox ağıllı olmağa çalışmayın.
17
30 июля '14 в 13:54 2014-07-30 13:54 Cavab 30 iyul 'da 13:54' də Liath tərəfindən verildi 2014-07-30 13:54

Yinelemeyi təklif etdiniz

 Dictionary<string,object> myDictionary = new Dictionary<string,object>(); //Populate your dictionary here foreach (KeyValuePair<string,object> kvp in myDictionary) { //Do some interesting things; } 

FYI, foreach dəyəri dəyərin obyekti olduqda işləmir.

9
28 окт. Xushi 28 oktyabrda cavablandırdı 2009-10-28 23:49 '09 at 11:49 PM 2009-10-28 23:49

Sözü təkrarlamaq üçün ən sadə forma:

 foreach(var item in myDictionary) { Console.WriteLine(item.Key); Console.WriteLine(item.Value); } 
8
02 окт. cavab Ron 02 oktyabr verilir 2016-10-02 07:00 '16 saat 07:00 'də 2016-10-02 07:00' də

Bəzən sadəcə siyahıda lazımi dəyərlərə ehtiyacınız varsa, bir sıra lüğət dəyərlərindən istifadə edin:

 foreach(var value in dictionary.Values) { // do something with entry.Value only } 

Http://alexpinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html , bu mesajı bildirir.

6
02 июля '14 в 4:55 2014-07-02 04:55 cavab 02 iyul '14 'də saat 4:55' də verilir 2014-07-02 04:55

MSDN'deki DictionaryBase sınıfının belgelerinde bu metodu tapdım:

 foreach (DictionaryEntry de in myDictionary) { //Do some stuff with de.Value or de.Key } 

DictionaryBase-dən miras qalan sinifdə normal fəaliyyət göstərə biləcəyi yeganə idi.

5
18 февр. Cavab 18 fevral tarixində Zannjaminderson tərəfindən verilir . 2009-02-18 02:51 '09 at 2:51 am 2009-02-18 02:51

MSDN-də rəsmi sənədlərə əsasən lüğəti təkrarlamaq üçün standart üsul:

 foreach (DictionaryEntry entry in myDictionary) { //Read entry.Key and entry.Value here } 
3
28 июля '16 в 13:58 2016-07-28 13:58 Cavab 28 iyul tarixində, '16 'saat 13:58 2016-07-28 13:58 tarixində verilir

.NET 4.0+-dan istifadə edəcəyəm və əvvəlcədən qəbul edilmiş versiyaya yenilənmiş bir cavab verəcəyəm:

 foreach(var entry in MyDic) { // do something with entry.Value or entry.Key } 
3
02 окт. cavab verildi yazanpro 02 oktyabr . 2014-10-02 02:17 '14 at 2:17 am 2014-10-02 02:17

Əgər deyirsinizsə, varsayılan bir koleksiyonun üzərində yinelemek isterseniz, bir Tercüman <> tətbiq edə biləcəyinizə inanıram, burada T, lüğətdə dəyər obyektinin növüdür və "bu" bir lüğətdir.

 public new IEnumerator<T> GetEnumerator() { return this.Values.GetEnumerator(); } 
2
09 дек. cavab mzirino 09 dekabr verilir . 2008-12-09 07:16 '08 at 07:16 2008-12-09 07:16

Cavabların çoxu foreach döngəsinə aid olduğundan, mənim 2 sentim əlavə etmək istədi. Aşağıdakı kodu nəzərinizə keçin:

 Dictionary<String, Double> myProductPrices = new Dictionary<String, Double>(); //Add some entries to the dictionary myProductPrices.ToList().ForEach(kvP => { kvP.Value *= 1.15; Console.Writeline(String.Format("Product '{0}' has a new price: {1} $", kvp.Key, kvP.Value)); }); 

Bu, '.ToList ()' üçün əlavə bir zəng əlavə olundu, bəlkə də, böyük lüğətlər ilə işləyərkən və paralel başlanğıcda bir parametr deyil / heç bir təsiri olmadıqda, foreach və bəzi list.Foreach () {} hamısı.

Ayrıca foreach döngünün içərisində "dəyər" xüsusiyyətinə dəyər verə bilməzsiniz. Digər tərəfdən, siz də "açarı" idarə edə bilərsiniz, bəlkə icra zamanı çətinliklərlə qarşılaşacaqsınız.

Yalnız düymələri və dəyərləri oxumaq istədiyiniz zaman, həmçinin IEnumerable istifadə edə bilərsiniz. () Seçin.

 var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } ); 
1
16 сент. 16 Sentyabrda Alexə cavab verildi . 2016-09-16 19:03 '16 saat 07:03 'da 2016-09-16 19:03
 var dictionary = new Dictionary<string, int> { { "Key", 12 } }; var aggregateObjectCollection = dictionary.Select( entry => new AggregateObject(entry.Key, entry.Value)); 
0
28 мая '15 в 18:00 2015-05-28 18:00 Cavab Pixar tərəfindən mayın 28-də, 15-də saat 18: 00-da verilmişdir

.NET Framework 4.7 ilə ayrışmayı istifadə edə bilərsiniz

 var fruits = new Dictionary<string, int>(); ... foreach (var (fruit, number) in fruits) { Console.WriteLine(fruit + ": " + number); } 

Bu kodu C # System.ValueTuple NuGet package aşağı versiyalarında işləmək üçün System.ValueTuple NuGet package əlavə edin və bir yerdə yaz

 public static class MyExtensions { public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple, out T1 key, out T2 value) { key = tuple.Key; value = tuple.Value; } } 
0
17 окт. Cavab Pavel 17 oktyabr. 2017-10-17 18:18 '17 'də 18:18' də 2017-10-17 18:18 'də

Standart şəkildə deyil, işləyənlər:

 Dictionary<string, int> dict = new Dictionary<string, int> { {"Foo", 1 }, {"Bar", 2 } }; dict.Select(kvp => { Console.WriteLine(kvp.Key + " - " + kvp.Value.ToString()); return kvp; }).Count(); 
0
05 июля '15 в 16:36 2015-07-05 16:36 cavab 05: 05-də saat 15: 00-da verilir

haqqında digər suallar və ya bir sual