2009-03-06 16 views
4

Oldukça yaygındır - özellikle kodunuzu daha fazla veriye dayalı hale getirmeye çalışırken, ilgili koleksiyonlar üzerinde yineleme yapmanız gerekir. Paralel diziler de tanımlanabilir ihtiyacım yokİlişkili değerler kümesinde yineleme için kullanılacak desen nedir?

items = [("DOC", "DocDate"), ("CON", "ConUserDate"), ("BAL", "BalDate")] 
for (entType, dateField) in items: 
    # do stuff with the associated entType and dateField 

: Ben gibi bir şey yazmak istiyorum, Python

string[] entTypes = {"DOC", "CON", "BAL"}; 
string[] dateFields = {"DocDate", "ConUserDate", "BalDate"}; 
Debug.Assert(entTypes.Length == dateFields.Length); 

for (int i=0; i<entTypes.Length; i++) 
{ 
    string entType = entTypes[i]; 
    string dateField = dateFields[i]; 
    // do stuff with the associated entType and dateField 
} 

: Mesela ben sadece bu gibi görünüyor kod parçası yazmayı bitirdim Dizilerimin aynı uzunlukta olduğunu iddia etmem gerekmiyor, öğeleri çıkarmak için bir dizin kullanmam gerekmiyor.

C# kullanarak bunu LINQ kullanarak yapmanın bir yolu gibi hissediyorum, ama ne olabileceğini anlayamıyorum. Birden çok ilişkili koleksiyonda yineleme yapmak için kolay bir yöntem var mı?

Düzenleme:

Bu biraz daha iyi, bence - en azından, durumda ben bildiriminde manuel koleksiyonlarını sıkıştırma lüksüne sahip nerede ve tüm koleksiyonları aynı nesneleri içerir nerede türü:

.NET 4.0'da bu kadar kod aşağıdaki gibi görünebilir, IEnumerable bir "Zip" uzantısı yöntemi ekliyoruz
List<string[]> items = new List<string[]> 
{ 
    new [] {"DOC", "DocDate"}, 
    new [] {"CON", "ConUserDate"}, 
    new [] {"SCH", "SchDate"} 
}; 
foreach (string[] item in items) 
{ 
    Debug.Assert(item.Length == 2); 
    string entType = item[0]; 
    string dateField = item[1]; 
    // do stuff with the associated entType and dateField 
} 
+0

biri belirleyici bir yerine bir şey yazmak için "daha sıkıştırılmış ama daha az okunabilir" yol isteyeyim Neden yapı veya sınıf? – Hamid

+0

30 veya 40 çift değeriniz varsa, aynı üye isimlerini 30 veya 40 kere yazmak zorunda kalmak kodu * daha * okunabilir yapmaz. –

cevap

3

:

foreach (var item in entTypes.Zip(dateFields, 
    (entType, dateField) => new { entType, dateField })) 
{ 
    // do stuff with item.entType and item.dateField 
} 

Şimdilik yapabileceğim en kolay şey, bunu bir döngü olarak bırakmak olduğunu düşünüyorum. "Diğer" diziyi referans alabileceğiniz püf noktaları vardır (örneğin bir dizin sağlayan Select() öğesinin aşırı yüklenmesini kullanarak) ancak bunların hiçbiri yineleme için basit olarak temiz değildir.

Here's a blog post about Zip as well as a way to implement it yourself. Bu arada gitmen gerek.

+0

Bu güzel, dört gözle bekliyorum – johnc

2

Bir struct oluşturun?

struct Item 
{ 
    string entityType; 
    string dateField; 
} 

Pythonic çözümünüzle hemen hemen aynı, tür güvenlidir.

0

Parçayı ve genel bir Listeyi kullanabilirsiniz.

List<Pair> list = new List<Pair>(); 

list.Add(new Pair("DOC", "DocDate")); 
list.Add(new Pair("CON", "ConUserDate")); 
list.Add(new Pair("BAL", "BalDate")); 

foreach (var item in list) 
{ 
    string entType = item.First as string; 
    string dateField = item.Second as string; 

    // DO STUFF 
} 

Çift, Web.UI'nin bir parçasıdır, ancak kendi özel sınıfınızı veya yapınızı kolayca oluşturabilirsiniz. Sadece satır içi listeleri bildirmek istiyorsanız

+0

Şu an yazdığımdan daha az kod değil; Aslında, daha fazla. İkiden fazla ilişkilendirilmiş listem varsa da bozulur. –

0

, tek adımda bunu yapabilir:

var entities = new Dictionary<string, string>() { 
    { "DOC", "DocDate" }, 
    { "CON", "ConUserDate" }, 
    { "BAL", "BalDate" }, 
}; 
foreach (var kvp in entities) { 
    // do stuff with kvp.Key and kvp.Value 
} 

onlar başka şeyler geliyorlar, biz çeşitli dan sözlükleri oluşturmak için uzatma yöntemlerinin bir grup var veri yapıları.

+0

Bunun iki sorunu: 1) ikiden fazla ilişkilendirilmiş listeyi işleyemez, 2) Sözlük, anahtarların üzerinde yinelenen kendi sırasını emer. Ama benim düzenime bak. –

1

Bu gerçekten diğer temalar üzerine bir varyasyon, ancak bu da hile yapacağını ...

var items = new[] 
      { 
       new { entType = "DOC", dataField = "DocDate" }, 
       new { entType = "CON", dataField = "ConUserData" }, 
       new { entType = "BAL", dataField = "BalDate" } 
      }; 

foreach (var item in items) 
{ 
    // do stuff with your items 
    Console.WriteLine("entType: {0}, dataField {1}", item.entType, item.dataField); 
} 
+0

Doğru cevap budur. – mquander

+0

Bu, maçalarda ihlal edilen DRY ilkesine abone olmadığınız sürece. Liste 50 öğe içeriyorsa, bu bir çok gereksiz koddur - özellikle ilk satırdaki her satırda, alan adları yanlış yazılmışsa derleme zamanı hataları oluşturma dışında bir şey yapmaz. –

İlgili konular