c# - 从 LINQ 获取范围组结果

标签 c# linq linq-group

我有以下数据

List<Trades> tradeList = new List<Trades>();
tradeList.Add(new Trades() { securityId = "JKH.N0000", principalAmount = "100.00", tradeDate ="20160401", accountNumber = "JKB831230063VN00" });
tradeList.Add(new Trades() { securityId = "JKH.N0000", principalAmount = "200.50", tradeDate = "20160402", accountNumber = "JKB547779605VN00" });
tradeList.Add(new Trades() { securityId = "COMB.N0000", principalAmount = "150.00", tradeDate = "20160403", accountNumber = "JKB831230063VN00" });
tradeList.Add(new Trades() { securityId = "JKH.N0000", principalAmount = "100.00", tradeDate = "20160409", accountNumber = "JKB547779605VN00" });
tradeList.Add(new Trades() { securityId = "GRAN.N0000", principalAmount = "200.00", tradeDate = "20160409", accountNumber = "JKB813384150VN00" });
tradeList.Add(new Trades() { securityId = "COMB.N0000", principalAmount = "100.00", tradeDate = "20160410", accountNumber = "JKB813384150VN00" });
tradeList.Add(new Trades() { securityId = "HNB.X0000", principalAmount = "100.00", tradeDate = "20160410", accountNumber = "JKB000009903FC00" });
tradeList.Add(new Trades() { securityId = "HNB.N0000", principalAmount = "100.00", tradeDate = "20160410", accountNumber = "JKB000000054LC00" });

我需要获取给定年龄组的 principalAmount 总和。所以我将输出可视化如下:

Age Group |   Sum(principalAmount)
0-25      |   v       
25-35     |   w
35-55     |   x
55-75     |   y
75 >      |   z

为此我做了以下事情

var rx = new Regex("JKB([0-9]{9})(V|X)N([0-9]{2})+", RegexOptions.IgnoreCase);

var q = tradeList
        .Where (x => rx.IsMatch(x.accountNumber))
        .Select(r => new
        {
            accountNo = r.accountNumber,
            dob = calculateDOB(r.accountNumber.Substring(3)),
            Age = calculateAge(calculateDOB(r.accountNumber.Substring(3))),
            Gender = int.Parse(r.accountNumber.Substring(3).Substring(2, 3)) > 500 ? "Female" : "Male",
            revenue = r.principalAmount
        });

然后将数据分组如下

var ceilings = new[] { 0, 25, 35, 55, 75 };
var q2 = q.GroupBy(item => ceilings.First(ceiling => ceiling >= item.Age));

Dictionary<int, decimal> counts = q2.ToDictionary(g => g.Key, (g => g.Sum(x => decimal.Parse(x.revenue.ToString()))));

string s = string.Empty;

foreach (KeyValuePair<int, decimal> entry in counts)
{
    s += s + string.Format("Key = {0}, Value = {1}", entry.Key, entry.Value) + Environment.NewLine;
}

MessageBox.Show(s);

但是我得到的数据输出为:

Key = 35, Value = 550.00 
Key = 75, Value = 300.50

我的问题是如何获取以下格式的字符串形式的键值:

Age Group |   Sum(principalAmount)
0-25      |   v       
25-35     |   w
35-55     |   x
55-75     |   y
75 >      |   z

I got direction on the following StackOverFlow Question and Answers

最佳答案

我假设 0 并不是真正的上限值。还假设,根据您引用的帖子,该列表不是固定的,因此我们需要一般性地解决。

获取天花板列表 - 我们将其称为 sourceCeilings。我假设这将是一个数组,而不是一个列表:

var sourceCeilings = new int?[] { 25, 35, 55, 75 };

我们想要一套“地板”作为您的天花板。你的问题推断“25”是一个范围的结束和下一个范围的开始。所以我们就这样吧。

var floors = new List<int?> { 0 };
floors.AddRange(sourceCeilings);

现在在上限末尾添加一个空值 - 我们需要为此转换为列表。需要 null 来配对“75 >”:

var ceilings = sourceCeilings.ToList();
ceilings.Add(null);

现在我们将两个列表压缩在一起,创建一个包含 Floor、Ceiling 和 Title 的列表:

var combined = floors.Zip(ceilings,
    (f, c) =>
        new
        {
            floor = f,
            ceiling = c,
            title = string.Format("{0} > {1}", f.Value, c.HasValue ? c.Value.ToString() : "")
        });

使用此列表,您可以在天花板上执行连接并选择键作为标题。

关于c# - 从 LINQ 获取范围组结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37137130/

相关文章:

c# - 如何在C#中成功下载一个.exe文件?

c# linq 遍历数据库中的层次结构数据

c# - Linq to 实体导航属性

c# - Pechkin HTML to PDF 该图像未显示在 pdf 中

C# 添加 List<string> 到 List<List<string>> 数组

c# - 具有 boolean 值的 Lambda 查询 GroupBy

c# - 将列表分成 3 组并选择每组中的最大值

c# - Linq 按日期分组(月)

c# - 好的编码? (多个消息循环)

c# - LINQ 中的返回模态平均值(模式)