2016-09-16 3 views
1

각 그룹 내에 여러 개의 이미지가 있고 하나의 이미지를 문자열 기준에 따라 추출해야하는 시나리오가 있습니다.우선 순위 조건에 따라 단일 항목을 얻는 가장 효율적인 방법

아래는 지금 수행되는 방식이며 작동합니다. 그러나, 확실하지 않은이 가장 효율적인 방법, 성능, 크기 인 경우, 어쩌면 너무 현명 연습

   foreach (var g in groups) 
       { 
        SomeType file = null; 

        if (file == null) 
        { 
         file = g.Where(i => 
           i.URL.Contains("StringA") 
           ).FirstOrDefault(); 
        } 
        if (file == null) 
        { 
         file = g.Where(i => 
            i.URL.Contains("StringB") 
           ).FirstOrDefault(); 
        } 
        if (file == null) 
        { 
         file = g.Where(i => 
           i.URL.Contains("StringC") 
           ).FirstOrDefault(); 
        } 
        if (file == null) 
        { 
         // etc... 
        } 
        if (file == null) 
        { 
         file = g.FirstOrDefault(); 
        } 
       } 
+1

너무 광범위 : 코드 스타일은 주제를 벗어나 부분을 무시하므로 분명히 루프로 리펙토링 할 수 있습니다 (질문 할 것 같지 않음). 성능 질문 - 숫자가 완전히 누락되었습니다. 및 유형을 사용하는 LINQ 공급자 유형 ... –

+0

LINQ (이 방법은 생각할 수 없다)보다 더 효율적인 방법이 있지만 –

+0

@AlexeiLevenkov, LINQ의 의미를 설명해 주시겠습니까? 공급자? System.Linq은 표준이며 종종 MoreLinq 라이브러리를 사용합니다 ... 결코 지루해하지 않았습니다. :) 나는 내 접근 방식에서 결코 확신하지 못했습니다 ... 다른 개발자가 생각하는 방식에 놀라는 것이 굉장합니다! – usefulBee

답변

2

난 당신이 약간 지루한이 답을 찾을 수 있습니다 두려워하지만 몇 가지 매우 impressive-을 찾기 위해 노력하고 피할 것 찾고 있지만 복잡한 linq 쿼리. 나는 그것이 할 수 있었다라고 확신한다. 그러나 그것은 두통의 가치가 없다.

모든 문자열을 배열에 붙이고 우선 순위에 따라 순서를 확인하십시오. 많은 수의 항목을 실행하지 않는 한 충분히 빠릅니다. db 쿼리를 실행하지 않고 있습니다. foreach 루프를 사용하면 데이터가 이미 메모리에 있음을 알 수 있습니다.

그래서, if 문 큰 잃게의 라인을 따라 뭔가를 목표 것 : 나는 매우 흥분하지 말했듯이

string [] my_list = new string [] {"StringA", "StringB", "StringC"}; 

foreach (var g in groups) 
{ 
    foreach (string s in my_list) 
    { 
     file = g.Where(i => i.URL.Contains(s)).FirstOrDefault(); 
     if (file != null) 
      break; 
    } 
    if (file == null) 
    { 
     file = g.FirstOrDefault(); 
    } 
} 

하지만 검색에 우선 순위를 변경하는 것이 쉬운 죽은 및 \ 또는 문자열을 추가하고 제거하십시오.

HTH,

아담.

+0

모든 가정은 정확합니다. 나는 오직 Contains 문을 편집하여 s 변수를 전달했다 ... 훌륭한 접근법 – usefulBee

+0

나는이 접근법을 적용했고 성능 향상에 놀랐다! 또한 매우 다양하며 앱 요구 사항과 다른 우선 순위에 따라 여러 목록을 만들 수 있습니다. 다행이야! – usefulBee

1
string [] my_list = new string [] {"StringA", "StringB", "StringC"}; 
foreach (var g in groups) 
{ 
    SomeType file = g.FirstOrDefault(i => my_list.Any(l=>i.Url.Contains(l))) 
            ?? g.FirstOrDefault(); 

} 
+0

마지막으로 댓글을 달았습니다. 접근 방식이 유망 해 보였지만 우선 순위를 보장하지는 못했습니다. StringA를 사용할 수있을 때 StringB와 C를 가진 항목을 발견했습니다. – usefulBee

0

string[] filters = new[] { "StringA", "StringB", "StringC" }; 

foreach (var g in groups) 
{ 
    SomeType file = filters.Select(s => g.FirstOrDefault(i => i.URL.Contains(s))) 
          .FirstOrDefault(m => m != null); 
} 
또는 당신이 어딘가에 결과 전체 루프를 교체하고 실제로 저장하려면 : 될 수

file = g.Where(somePredicate).FirstOrDefault();

같은 표현을 : BTW

var files = groups.Select(g => filters.Select(s => g.FirstOrDefault(i => i.URL.Contains(s))) 
             .FirstOrDefault(m => m != null)); 

로 작성3210

file = g.FirstOrDefault(somePredicate);

관련 문제