2009-03-06 3 views
4

특히 코드를 데이터 중심으로 만들려고 할 때와 같이 관련 컬렉션을 반복해야 할 때가 많습니다. 병렬 배열을 선언하는 내가 필요하지 않은연관된 값 집합을 반복하는 데 사용할 패턴은 무엇입니까?

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

: 내가 좋아하는 뭔가를 쓰는 것, 파이썬에서

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 
} 

: 예를 들어, 난 그냥 같이 보입니다 코드의 조각을 작성 완료 내 배열의 길이가 같다고 주장 할 필요가 없습니다. 색인을 사용하여 항목을 가져올 필요가 없습니다.

LINQ를 사용하여 C#에서이 작업을 수행 할 수있는 방법이 있지만 사용하지 못할 수도 있습니다. 여러 개의 연관된 컬렉션을 반복하는 몇 가지 쉬운 방법이 있습니까?

편집 :

이 조금 더, 내가 생각 - 적어도, 경우에 내가 선언에 수동으로 컬렉션을 압축하는 사치를 가질 경우, 모든 컬렉션은 동일의 객체를 포함 할 경우 유형 :

.NET 4.0에서 그들이 그렇게 코드가 같은 것을 볼 수 있었다,를 IEnumerable "우편 번호"확장 메서드를 추가하는
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

하나는 정의 대신에 뭔가를 작성하는 "더 압축 미만 읽을 수있는"방법을 원하는 것이 왜 구조체 또는 클래스? – Hamid

+0

30 개 또는 40 쌍의 값이있는 경우 동일한 멤버 이름을 30 번 또는 40 번 쓰지 않아도 코드 *를 더 읽을 수 없습니다. –

답변

3

:

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

당분간은 for 루프로 남겨 두는 것이 가장 쉬운 방법이라고 생각합니다. "(예를 들어 인덱스를 제공하는 Select()의 오버로드를 사용하여)"다른 "배열을 참조 할 수있는 트릭이 있지만 어느 것도 이터레이터의 경우처럼 깨끗하지 못합니다.

Here's a blog post about Zip as well as a way to implement it yourself. 그 동안 당신을 가야합니다.

+0

멋지 네요. 기대하고 있습니다. – johnc

2

구조체를 만드시겠습니까?

struct Item 
{ 
    string entityType; 
    string dateField; 
} 

유형 안전을 제외하고는 Python 솔루션과 거의 같습니다.

0

쌍과 일반 목록을 사용할 수 있습니다.

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 
} 

페어는 Web.UI에 포함되어 있지만 사용자 정의 클래스 또는 구조체를 쉽게 만들 수 있습니다. 그냥 인라인 목록을 선언하려면

+0

그게 내가 쓰는 코드보다 적지 않습니다. 사실, 그 이상입니다. 또한 두 개 이상의 관련 목록이있는 경우 세분화됩니다. –

0

, 당신이 한 번에 그 작업을 수행 할 수 있습니다

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 
} 

을 그들이 다른 것들에서 오는 경우, 우리는 다양한에서 사전을 구축하는 확장 메서드의 무리가 데이터 구조.

+0

두 가지 문제 : 1) 두 개 이상의 관련 목록을 처리 할 수 ​​없습니다. 2) 사전이 키를 반복 할 때 자체 순서를 지정합니다. 하지만 내 편집을 봐라. –

1

이 정말 다른 주제의 변형이지만,이 또한 트릭을 할 것입니다 ...

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

올바른 대답입니다. – mquander

+0

DRY 원리에 가입하지 않으면 스페이드에 위배됩니다. 목록에 50 개의 항목이 포함되어 있으면 많은 중복 코드가 발생합니다. 특히 첫 번째 이후의 모든 행에서 필드 이름은 철자가 틀린 경우 컴파일 타임 오류를 만드는 것을 제외하고는 아무 것도하지 않습니다. –

관련 문제