2013-12-16 2 views
1

에서 객체의 목록에서 합계를 얻을 :나는 개체의 목록을 가지고 LINQ의 C#을

List<Maths> mObjs = new List<Maths>(); 
mObjs.Add(new Maths{ Name = "Jack", M1 = 10, M2 = 5, M3 = 0, M4 = 2, M5 =1 }); 
mObjs.Add(new Maths { Name = "Jill", M1 = 2, M2 = 3, M3 = 4, M4 = 1, M5 = 0 }); 
mObjs.Add(new Maths { Name = "Michel", M1 = 12, M2 = 15, M3 = 10, M4 = 12, M5 = 11 }); 

가 지금은 세 사람을위한 총 집계 값을 계산해야합니다. 아마 새로운 다른 클래스, 아래의 결과를 얻을 필요가

List<Results> mRes = new List<Results>(); 

public class Results{ 
    public string Name { get; set; } 
    public int TotalValue { get; set; } 

} 

mRes.Name = "M1" 
mRes.TotalValue = 24; 

mRes.Name = "M2" 
mRes.TotalValue = 23; 

mRes.Name = "M3" 
mRes.TotalValue = 14; 

mRes.Name = "M4" 
mRes.TotalValue = 15; 


mRes.Name = "M5" 
mRes.TotalValue = 12; 

누군가가 LINQ 쿼리를 사용 mObjs에서이 데이터를 얻을 수있는 방법을 조언 해 줄 수 있습니다? 우리는 for를 사용하여이를 수행 할 수 있지만 linq 쿼리를 사용하여 코드를 줄이는 데 더 좋은 방법이 있는지 알고 싶습니다. 코드 줄을 줄이고 많은 다른 위치에서 비슷한 요구 사항을 가지고 있기 때문에 foreach 또는 fors 매번.

도와주세요. ??

답변

4
당신은 * 그럼 당신은 단순히

var mRes = dlookups.Select(x => new Results { 
               Name= x.Key, 
               TotalValue = mObjs.Sum(x.Value) 
          }).ToList(); 

업데이트 BEGIN 할 수

var lookups = new Dictionary<string,Func<Maths,int>> { 
    {"M1", x => x.M1 }, 
    {"M2", x => x.M2 }, 
    {"M3", x => x.M3 }, 
    {"M4", x => x.M4 }, 
    {"M5", x => x.M5 }, 
}; 

을 선택 이름과 필드를 모두 나열하는 사전 선택 목록을 사용할 수 있습니다

코멘트에 대한 응답으로

람다 식은 소스 클래스에서 int까지의 함수입니다. 예를

class Sub1 { 
    string M3 {get;set;} 
    int M4 {get;set;} 
} 

class Math2 { 
    string Name {get;set;} 
    string M1 {get;set;} 
    string M2 {get;set;} 
    Sub1 Sub {get;set;} 
} 

var lookups = new Dictionary<string,Func<Math2,int>> { 
    { "M1", x => int.Parse(x.M1) }, 
    { "M2", x => int.Parse(x.M2) }, 
    { "M3", x => int.Parse(x.Sub.M3) }, 
    { "M4", x => int.Parse(x.Sub.M4} } 
}; 

아니면 체크인 약간의 오류를 넣어하려는 경우, 당신이 사용하는 기능이나 중 하나가 코드를 포함 할 수 있습니다 들어

. 당신이 더 당신이 조회 사전을 구축하는 반사를 사용할 수 있습니다 가고 싶은 경우

int GetInt(string source) { 
    if (source == null) return 0; 
    int result; 
    return int.TryParse(source, out result) ? result : 0; 
} 

var lookups = new Dictionary<string,Func<Math2,int>> { 
    { "M1", x => { 
        int result; 
        return x == null ? 0 : (int.TryParse(x,out result) ? result : 0); 
       }, 
    { "M2", x => GetInt(x) }, 
    { "M3", x => x.Sub == null ? 0 : GetInt(x.Sub.M3) }, 
    { "M4", x => x.Sub == null ? 0 : x.Sub.M4} 
}; 

END는

업데이트되었습니다.

다음은 클래스의 모든 Integer 속성에 대한 조회를 생성하는 도우미 함수입니다.

public Dictionary<string,Func<T,int>> GenerateLookups<T>() where T: class { 
    // This just looks for int properties, you could add your own filter 
var properties = typeof(T).GetProperties().Where(pi => pi.PropertyType == typeof(int)); 

var parameter = Expression.Parameter(typeof(T)); 

    return properties.Select(x => new { 
    Key = x.Name, 
    Value = Expression.Lambda<Func<T,int>>(Expression.Property(parameter,x),parameter).Compile() 
    }).ToDictionary (x => x.Key, x => x.Value); 

} 

지금 당신은 다만 할 수 있습니다 당신은 고용해야 할 수도 있습니다,

mRes.Add(new Results() { Name = "M1", TotalValue = mObjs.Sum(x => x.M1) }); 

프로그래밍 모든 클래스의 속성을 반복하려면 :

var mRes=GenerateLookups<Maths>().Select(x => new Results 
    { 
    Name = x.Key, 
    TotalValue = mObjs.Sum(x.Value) 
    }).ToList(); 
+0

이걸 시도해 주셔서 감사합니다. 내가 다시 돌아올 께 – mmssaann

+0

절대적으로 똑똑합니다 .. 고마워 .. 많이 .. – mmssaann

+0

에 직면 해 있습니다. 다른 클래스 포인트는 문자열 변수에 저장됩니다. 해당 문자열 속성을 int로 변환하려면 어떻게해야합니까? – mmssaann

1

매우 영리하지만 효율적이고 읽을 수 없습니다 :

int m1Total= 0; 
int m2Total= 0; 
int m3Total= 0; 
int m4Total= 0; 
int m5Total= 0; 
foreach(Maths m in mObjs) 
{ 
    m1Total += m.M1; 
    m2Total += m.M2; 
    m3Total += m.M3; 
    m4Total += m.M4; 
    m5Total += m.M5; 
} 
List<Results> mRes = new List<Results> 
{ 
    new Results{ Name = "M1", TotalValue = m1Total }, 
    new Results{ Name = "M2", TotalValue = m2Total }, 
    new Results{ Name = "M3", TotalValue = m3Total }, 
    new Results{ Name = "M4", TotalValue = m4Total }, 
    new Results{ Name = "M5", TotalValue = m5Total }, 
}; 

결과 :

Name: "M1" TotalValue: 24 
Name: "M2" TotalValue: 23 
Name: "M3" TotalValue: 14 
Name: "M4" TotalValue: 15 
Name: "M5" TotalValue: 12 

편집 : 속성은 항상이 다섯 내가 돈이 있다면 당신은 명시 적으로 LINQ를 요구 한 이후 왜 LINQ를 사용해야하는지 알지 못합니다. 숫자가 바뀔 수 있다면 나는 다른 구조를 사용할 것입니다.

당신은 예를 들어 Measurement 이름과 값을 저장하는 다른 클래스입니다 대신 여러 속성의

  • 하나의 List<Measurement>을 사용할 수 있습니다 또는 당신은 효율적인 검색을 위해
  • Dictionary<string, int>를 사용할 수 있습니다.
0

당신은이 같은 몇 가지 일을 시도 할 수 반사.

관련 문제