2014-10-14 3 views
1

나는 설문지에 대한 사람들의 답변 목록을 가지고 있습니다. 답변은 현재 문자열 배열이므로 내 객체는 같습니다.동일한 답변을 모두 찾으십시오.

List<string[]> answers = new List<string[]>() 
{ new string[]{"T","A","T","F","B"}, 
    new string[]{"F","A","T","F","B"}, 
    new string[]{"T","A","F","F","B"} 
}; 

모든 값이 같은 배열 색인과 값을 찾아야합니다. 생성 된 객체가 될 수 string[]

{"","A","","F","B"} 

거나 같을 것이라고 정의 객체 튜플의 일부 유형

추천 {1, "A"}, {3, "F"}, {4 'B'}

모든 문자열 배열의 길이가 같다고 가정 할 수 있습니다.

나는 무차별 대입과 루프를 통해이 작업을 수행 할 수 있지만 Linq를 통해보다 효율적인 클리너 방법이 있는지 궁금합니다.

Linq는 단지 내부적으로 루프를 사용하며 절약은 코드 라인이며 로컬 변수를 생성해야한다는 유일한 질문입니다.

업데이트 : 떨어져가는 무엇 OR 매퍼 및 Vajura 나는 두 개의 루프

생각하고 있었는데 나에게 각 문자열 []의 길이를 제공하고 나에게 무엇을 제공 답변의 첫 번째 세트를 가져옵니다 대답은 있어야합니다. 첫 번째 사람이 다른 모든 비-A는 자동으로 인덱스의 자격을 박탈 할 대답 유일하더라도이 같은

for each index in string[] 
    answer = List[0][index] 
    for i=1 to List.Count - 1 
     compare answer to List[i][index] 
     if false exit loop 

    if we made it through it is good 
+7

** Linq **는 문법적 인 설탕 *이며 일리노이로 컴파일하면 후드 아래에서 루프 등이 사용됩니다. – christiandev

+1

* 루프 *를 사용하는 것은 * 무차별 강제 *를 사용하는 것을 의미하지 않습니다. 그리고 네, LINQ는 내부적으로 루프를 사용하기 때문에 적절히 작성된 루프와 비교할 때 실행 효율성이 본질적으로 향상되지 않습니다. –

+2

이 솔루션에는 다른 방법으로 "무력"이 없습니다. 모든 값을 확인해야합니다. 그것은 당신이 그것을 많이 최적화 할 수 있다고 말하면서 두 번째 문자열 배열의 첫 번째 인덱스가 이미 다음 다른 배열을 위해 더 이상 그 값을 검사 할 필요가 없다면 처음에는 다르다. 당신이 그것을 최적화 할 수있는 다른 작은 것들이있을 것입니다. – Vajura

답변

6

뭔가 작업을해야합니다 :

여기
answers 
.SelectMany(x => x.Select((y, idx) => new { c = y, index = idx })) // 1 
.GroupBy(x => x) // 2 
.Where(x => x.Count() == answers.Count) // 3 
.ToDictionary(x => x.Key.index, x => x.Key.c); // 4 

이 작업 fiddle

입니다

설명은 다음과 같습니다

  1. 목록을 평평하고 각 레트를 선택 어하고
  2. 이 까다로운 부분입니다 (익명 형식 그래서 우리는 같은 시간에 문자와 인덱스로 그룹화하는 속성 값을 기준으로 비교) 익명의 유형 문자와 인덱스에 의해 쌍
  3. 그룹에 지수, answer.Count 많은 항목이있는 그룹을 얻으십시오. 따라서 모든 내부 배열에 문자 - 색인 쌍이 있는지 확인하십시오. 즉, 모든 배열의 동일한 색인에있는 문자입니다.
  4. 마지막으로 키가 색인이고 값이 문자 인 사전에 그룹을 넣습니다.
    var results = answers.Aggregate(answers[0],(p, n) => p.Zip(n, (pi, ni) => pi==ni ? pi : "") 
                     .ToArray()) 
            .ToArray(); 
    

    당신이 실제 응용 프로그램에서 이것을 사용하기로 결정한 경우 나는 그것이 어떻게 작동하는지 문서화 선명하게 것이지만

    어떤 결과 :
+0

휴식 주셔서 감사합니다. – Mike

1

음, 그냥 당신에게 말을 여기에 Linq는 방법입니다 방법.

실제로 이것은 올바르게 설계된 루프보다 효율적이지 않으며 코드 가독성은 간결함과 다른 모든 점이 동일하다는 점에서 더 중요합니다.

1

LINQ에서 훨씬 간단한 방법 : 성능에 대해 걱정하는 경우가 5 시간 빠른 목록에 foreach하는 것보다이기 때문에

string[] result = answers 
     .Aggregate((a, b) => 
     a.Select(a1 => (b[Array.IndexOf(a,a1)] == a1) ? a1 : "").ToArray()); 

, 나는, 배열에 for 루프를 사용하도록 권장합니다 (그리고 Linq보다 훨씬 빠름). 그것에 대해 몇 가지 기사가 있지만 꽤 흥미로운 this을 발견했습니다. 반면, Linq는 읽기 쉽고 우아합니다 (오케이, 그냥 제 생각입니다). 배열이 너무 길지 않거나 성능에 신경 쓰지 않으면이 Linq 메서드를 사용하는 것이 좋습니다.

관련 문제