[英]LINQ Group Nested List To Restructure Data
我有一个从服务传递的自定义对象的嵌套列表作为JSON我需要重组为一个新对象。 这是嵌套列表包含的对象:
public class Alt
{
public Member Member { get; set; }
public Claim OriginalClaim { get; set; }
public Claim AltClaim { get; set; }
public double Savings { get; set; }
}
对于每个成员和OriginalClaim,可以有一个或多个AltClaim。 所以我要做的就是为每个Member / OriginalClaim获取每个AltClaim。 我将映射数据的新对象如下所示:
public class Alternative
{
public Member Member { get; set; }
public Claim OriginalClaim { get; set; }
public List<AlternativeClaim> AlternativeClaims { get; set; }
}
public class AlternativeClaim
{
public Claim AltClaim { get; set; }
public double Savings { get; set; }
}
我已经能够通过LINQ对事物进行分组,但它正在生成一个Alternative列表,其中Member和OriginalClaim的重复次数与AlternativeClaims一样多。 这是我到目前为止的代码:
public void Test(List<List<Alt>> alternatives)
{
var test = from alts in alternatives
from alt in alts
group alts by new { alt.Member, alt.OriginalClaim } into a
select a;
foreach (var a in test)
{
Console.WriteLine("Auth {0}", a.Key.OriginalClaim.Id);
Console.WriteLine("MemberId {0}", a.Key.Member.Id);
foreach (var alt in a.SelectMany(x => x))
{
[write out alt.AltClaim properties in console here]
}
}
}
我相信我的问题在于LINQ查询。 我对LINQ并不十分熟悉,那么有没有人可以帮助我形成这个(或者至少指出我正确的方向)所以我没有得到重复的东西? 谢谢!!
编辑(解决方案):
对我有用的解决方案是以下两个答案的组合。 接受的答案是我使用的LINQ查询,但如果没有Thomas F的答案 ,我无法正确分组。 在我分组的类上实现IEquatable <>是关键。
非常感谢你们! 你在这个问题上帮助了我很多。
var alts = alternatives.SelectMany(x => x);
var res = alts.GroupBy(alt => Tuple.Create(alt.Member, alt.OriginalClaim))
.Select(g => new Alternative
{
Member = g.Key.Item1,
OriginalClaim = g.Key.Item2,
AlternativeClaims = g.Select(x => new AlternativeClaim {AltClaim = x.AltClaim, Savings = x.Savings}).ToList()
});
foreach (var a in res)
{
Console.WriteLine("Auth {0}", a.OriginalClaim.Id);
Console.WriteLine("MemberId {0}", a.Member.Id);
foreach (var alt in a.AlternativeClaims.OrderByDescending(c => c.Savings))
{
Console.WriteLine("\tSavings = {0};Id = {1};",alt.Savings, alt.AltClaim.Id);
}
}
给出输出:
Auth 51
MemberId 50
Savings = 696969;Id = 513;
Savings = 6969;Id = 512;
Savings = 69;Id = 511;
Auth 52
MemberId 50
Savings = 1002;Id = 522;
Savings = 100;Id = 521;
Auth 102
MemberId 100
Savings = 1022;Id = 1022;
Savings = 1021;Id = 1021;
测试代码
[Test]
public void Test()
{
var member1 = new Member {Id = 50};
var member1Claim1 = new Claim {Id = 51};
var member1Claim2 = new Claim {Id = 52};
var member2 = new Member { Id = 100 };
var member2Claim1 = new Claim { Id = 101 };
var member2Claim2 = new Claim { Id = 102 };
var alternatives = new List<List<Alt>>()
{
new List<Alt>
{
new Alt
{
Member = member1,
OriginalClaim = member1Claim1,
AltClaim = new Claim {Id = 511},
Savings = 69
},
new Alt
{
Member = member1,
OriginalClaim = member1Claim1,
AltClaim = new Claim {Id = 512},
Savings = 6969
},
new Alt
{
Member = member1,
OriginalClaim = member1Claim1,
AltClaim = new Claim {Id = 513},
Savings = 696969
},
new Alt
{
Member = member1,
OriginalClaim = member1Claim2,
AltClaim = new Claim {Id = 521},
Savings = 100
},
new Alt
{
Member = member1,
OriginalClaim = member1Claim2,
AltClaim = new Claim {Id = 522},
Savings = 1002
}
},
new List<Alt>
{
new Alt
{
Member = member2,
OriginalClaim = member2Claim2,
AltClaim = new Claim {Id = 1021},
Savings = 1021
},
new Alt
{
Member = member2,
OriginalClaim = member2Claim2,
AltClaim = new Claim {Id = 1022},
Savings = 1022
}
}
};
}
为了完整性:
public class Alt
{
public Member Member { get; set; }
public Claim OriginalClaim { get; set; }
public Claim AltClaim { get; set; }
public double Savings { get; set; }
}
public class Claim
{
public int Id { get; set; }
}
public class Member
{
public int Id { get; set; }
}
public class Alternative
{
public Member Member { get; set; }
public Claim OriginalClaim { get; set; }
public List<AlternativeClaim> AlternativeClaims { get; set; }
}
public class AlternativeClaim
{
public Claim AltClaim { get; set; }
public double Savings { get; set; }
}
您的会员和索赔课程是否实施IEquatable?
如果没有,我怀疑分组不起作用,因为成员和声明实例正在通过引用进行比较。 并且由于您已经提到您从服务接收数据为JSON,因此您的所有Alts很可能具有不同的Member和Claim实例。 因此,即使它们的属性具有相同的值,它们也不会属于同一组。
要使您的分组正常工作,您可以执行以下操作之一:
如果可用,请从成员和声明中选择一个唯一标准(如ID或名称)并按其分组:
var test = from alts in alternatives from alt in alts group alts by new { MemberId = alt.Member.Id, OriginalClaimId = alt.OriginalClaim.Id } into a select a; foreach (var a in test) { Console.WriteLine("Auth {0}", a.Key.OriginalClaimId); Console.WriteLine("MemberId {0}", a.Key.MemberId); foreach (var alt in a.SelectMany(x => x)) [write out alt.AltClaim properties in console here] }
为您的会员和索赔实施IEquatable和IEquatable。
public class Member : IEquatable<Member> { public bool Equals(Member other) { return Id == other.Id; } public override bool Equals(object obj) { var other = obj as Member; if (other == null) return false; return Equals(other); } public override int GetHashCode() { // Whenever IEquatable is implemented, GetHashCode() must also be overridden. return Id.GetHashCode(); } // Rest of the class... }
尝试alternatives.SelectMany(alt => new { alt.Member, alt.OriginalClaim })
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.