2017-11-07 16 views
0

람다에 코드를 넣고 싶지만 붙어 있습니다.값에 따라 람다 쿼리가 필요한 경우

기본적으로 : 배열 개체에 자체 연간 사양 및 ID가있는 4 명의 멤버가 포함되어있는 경우. 그러나 배열에는 같고 다른 ID와 연도를 가진 더 많은 멤버가 포함될 수 있습니다 (결코 같은 ID와 같은 해).

회원 배열 :

array[0]: Id 1 Year 2010 
array[1]: Id 2 Year 2010 
array[2]: Id 1 Year 2008 
array[3]: Id 1 Year 2009 

첫째 - 나는 그들이 또한 배열에 또 다른 해가있는 경우 2010 년 (동일한 ID, 다른 년) 특정 아이디를 가진 모든 배열 구성원을 삭제합니다. 따라서이 경우 [0]은 삭제하고 다른 멤버는 삭제하지 않으려합니다.

두 번째 - 이 경우에는 2010 년 이후의 다음 연도를 2009 년 ID 1으로 유지하고 싶습니다. [2]도 삭제하려고합니다. (왜 내가 아래에있는 코드의 비교를 위해 그들을 int로 변환하는 이유 인 문자열인가?)

다음은 루프를 피하기 위해 람다 전문가의 도움이 필요한 루프에 대한 코드입니다.

var x = Member.Length; 

for (int i = 0; i < x; i++) 
{ 
    var y = Member[i].id; 
    for (int j = i; j < x; j++) 
    { 
     var z = Member[j].id; 
     if (i != j) 
     { 
      if (y == z) 
      { 
       if (Member[i].year == "2010") 
       { 
        Member = Member.Where(w => w != Member[i]).ToArray(); 
        i--; 
        j--; 
        x--; 
        break; 
       } 

       var tempI = Convert.ToInt32(Member[i].year); 

       var tempJ = Convert.ToInt32(Member[j].year); 

       if (tempI > tempJ) 
       { 
        Member = Member.Where(w => w != Member[j]).ToArray(); 
        i--; 
        j--; 
        x--; 
        break; 
       } 
      } 
     } 
    } 
} 
+4

"다음은 해석하는 방법입니다 루프를 피하기 위해 전문가의 도움이 필요한 람다 (Lambda)의 도움을받는 코드가 "왜 Linq가이 모든 것을 다르게 할 것인가? 보통은 복잡성을 숨기기 위해 모든 일을 수행합니다. 이는 나쁜 것입니다. 이해할 수없는 코드를 사용하여 코드를 지나치게 복잡하게 만들면 안됩니다. 대신 이해하기 쉬운 코드에 대한 투쟁이 * 작동합니다 *. – HimBromBeere

+0

@HimBromBeere에 대해 알아 보려면 아는 것을 사용하십시오. 네가하는 일이 있다면 다른 일에 편안함을 느낄 때까지 붙어 라. 확률은 좋다. 다른 것 (예 : 적은 코드 행)은 외관을 정리 만하지만 단순화는 거의하지 않는다. – gilliduck

+1

@ gilliduck "이상한 점은 외모 만 정리하는 것 ..."음, 그래. 이것이 코드를 더 쉽게 읽을 수있게 해주는 방법입니다. 특히 실제로 코드를 작성하지 않은 다른 사람들은 코드를 더 쉽게 읽을 수 있습니다. LINQ 또는 기본 제어 흐름이든 상관없이 깨끗한 코드를 작성하는 법을 배워야합니다. –

답변

0

쿼리하는 기본 컬렉션을 변경하는 데 LINQ를 사용하지 않는 경향이 있습니다. 아래 코드는 각 멤버에 대해 가장 최근의 항목을 두 개까지 선택합니다.

var result = new List<MemberClass>(); 
var groups = Member.OrderBy(m => m.Id).ThenByDescending(m => m.Year).GroupBy(m => m.Id).ToList(); 
groups.ForEach(c => result.AddRange(c.Take(2))); 

원래 배열 대신 result을 사용하십시오.

실적이 귀하를위한 고려 사항인지는 확실하지 않습니다. 컬렉션의 성장에 따라 위의 코드가 느려질 수 있습니다.

0

귀하의 설명과 요구 사항이 호환되지 않습니다,하지만 여기에 하나 개의 해석입니다 : 내가 요구 사항이 많은 이해가되지 않습니다 동의

public class Member 
{ 
    public int Id { get; set; } 
    public string Year { get; set; } 
} 

var items = (new List<Member>() { 
    new Member() { Id=1, Year="2010" }, 
    new Member() { Id=2, Year="2010" }, 
    new Member() { Id=1, Year="2008" }, 
    new Member() { Id=1, Year="2009" } 
}).ToArray(); 

// Group everythnig by year, then only keep the highest id 
var firstFiltered = items 
    .GroupBy(
     x => x.Year, 
     x => x.Id, 
     (year, ids) => new Member() 
         { 
          Id = ids.Last(), 
          Year = year 
         }); 

var secondFiltered = firstFiltered 
    // Only keep years before 2010 
    .Where(x => String.Compare(x.Year, "2010") == -1) 
    // Then order by Id then Year 
    .OrderBy(x => x.Id) 
    .ThenBy(x => x.Year) 
    // And only keep the last/most recent year 
    .GroupBy(
     x => x.Id, 
     x => x.Year, 
     (id, years) => new Member() 
         { 
          Id = id, 
          Year = years.Last() 
         }); 
1

그러나 이것은 내가

var Member = new[] 
      { 
       new { id = 1, year = "2010" }, 

       new { id = 2, year = "2010" } , 

       new { id = 1, year = "2008" } , 

       new { id = 1, year = "2009" } 
      }; 

      var results = from item in Member.Select(x => new { x.id, Year = Convert.ToInt32(x.year), item = x }) 
         group item by item.id into sameItems 
         let order = sameItems.OrderByDescending(x => x.Year) 
         let first = order.ElementAtOrDefault(0) 
         let second = order.ElementAtOrDefault(1) 
         select first.Year == 2010 && second != null ? second.item : first.item; 

      foreach (var item in results) 
      { 
       System.Console.WriteLine($"id:{item.id},year:{item.year}"); 
      }