List<classObject> 对 C# 中的对象进行分组
List<classObject> group by on the objects in C#
我需要根据对象内的另一个列表对 class 个对象的列表进行分组。
class TransactionObject
{
public int ProjectId { get; set; }
public string uniqueId { get; set; }
public string OrgNumber { get; set; }
public string OrgName { get; set; }
public List<TransactionValue> TransactionValue{ get; set; } = new List<TransactionValue>();
public class TransactionValue
{
public DateTime TrnDate { get; set; }
public decimal EURTrans { get; set; }
public decimal LocaTrans { get; set; }
public decimal BrokeragePercentage { get; set; }
}
}
现在 class,我创建了一个对象列表。
var TransactionList = new List<TransactionObject>();
我想获取 Unique ProjectsIdm OrgName 的列表以及基于 TrnDate 的分组依据的 EUR Trans、Local Trans 的总和。
示例:
ProjectId OrgName Trn Date EUR Trns Local Trns
543332 Organization 1 1-Jan-22 100 150
543332 Organization 1 1-Jan-22 150 20
我需要:
对不起,我的错误,我编辑了我需要的正确输出
ProjectId OrgName Trn Date EUR Trns Local Trns
543332 Organization 1 1-Jan-22 250 170
我尝试了什么:
List<TransactionObject> result = TransactionList .GroupBy (g => new {
g.HoldingName, g.TransactionValues.First().TrntDate })
.Select(g => g.First())
.ToList();
我试过了,但它对列的总和没有帮助,我擅长 Java 但 C# 新手请帮助我。我已经超过了这个对象的最后期限。
我认为将操作分为两个阶段可能会有所帮助。
var flattened = TransactionList
.SelectMany(
collectionSelector: o => o.Transactions,
resultSelector: (fullObject, transaction) => new { fullObject.ProjectId, fullObject.OrgName, Transaction = transaction });
var grouped = flattened
.GroupBy (t => new {t.ProjectId, t.OrgName, t.Transaction.TrnDate })
.Select( g => new
{
g.Key.ProjectId,
g.Key.OrgName,
g.Key.TrnDate,
SumEURTrans = g.Sum( t => t.Transaction.EURTrans),
SumLocaTrans = g.Sum( t => t.Transaction.LocaTrans)
})
.ToList();
foreach (var t in grouped)
{
Console.WriteLine($"{t.ProjectId}\t{t.OrgName}\t{t.TrnDate}\t{t.SumEURTrans}\t{t.SumLocaTrans}");
}
这会产生
543332 Organization 1 1-Jan-22 250 170
543332 Organization 1 2-Jan-22 450 470
543333 Organization 1 1-Jan-22 250 170
对于
的示例输入
var TransactionList = new [] {
new TransactionObject
{
ProjectId = 543332,
OrgName = "Organization 1",
Transactions = new List<TransactionObject.TransactionValue>
{
new TransactionObject.TransactionValue
{
TrnDate = "1-Jan-22",
EURTrans = 100,
LocaTrans = 150
},
new TransactionObject.TransactionValue
{
TrnDate = "1-Jan-22",
EURTrans = 150,
LocaTrans = 20
}
,new TransactionObject.TransactionValue
{
TrnDate = "2-Jan-22",
EURTrans = 200,
LocaTrans = 250
},
new TransactionObject.TransactionValue
{
TrnDate = "2-Jan-22",
EURTrans = 250,
LocaTrans = 220
}
}
},
new TransactionObject
{
ProjectId = 543333,
OrgName = "Organization 1",
Transactions = new List<TransactionObject.TransactionValue>
{
new TransactionObject.TransactionValue
{
TrnDate = "1-Jan-22",
EURTrans = 100,
LocaTrans = 150
},
new TransactionObject.TransactionValue
{
TrnDate = "1-Jan-22",
EURTrans = 150,
LocaTrans = 20
}
}
}
};
这将按 {t.ProjectId, t.OrgName, t.Transaction.TrnDate}
对所有对象进行分组,您需要决定这是否是您想要的(一个示例替代方案是仅在每个 TransactionObject
中分组)。
如果我没理解错的话 - 你可以这样一次性完成 运行:
public void GroupTransactions(TransactionObject[] transactionObjects)
{
var results = transactionObjects
// build a flat list of values to have both transactionObject and value for every transactionValue
.SelectMany(obj => obj.TransactionValues.Select(value => (obj, value)))
.GroupBy(tuple => new {tuple.obj.ProjectId, tuple.obj.OrgName, tuple.value.TrnDate})
// Get sums for every group. You can use '.Aggregate()' method instead of this custom GetSum but it seems less readable to me.
.Select(group => (group.Key, sum: GetSum(group.Select(tuple => tuple.value))))
.ToArray();
foreach (var result in results)
Console.WriteLine($"{result.Key.ProjectId} {result.Key.OrgName} {result.Key.TrnDate} {result.sum.euro} {result.sum.local}");
}
private static (decimal euro, decimal local) GetSum(IEnumerable<TransactionObject.TransactionValue> values)
{
decimal euro = 0, local = 0;
foreach (var value in values)
{
euro += value.EURTrans;
local += value.LocaTrans;
}
return (euro, local);
}
我需要根据对象内的另一个列表对 class 个对象的列表进行分组。
class TransactionObject
{
public int ProjectId { get; set; }
public string uniqueId { get; set; }
public string OrgNumber { get; set; }
public string OrgName { get; set; }
public List<TransactionValue> TransactionValue{ get; set; } = new List<TransactionValue>();
public class TransactionValue
{
public DateTime TrnDate { get; set; }
public decimal EURTrans { get; set; }
public decimal LocaTrans { get; set; }
public decimal BrokeragePercentage { get; set; }
}
}
现在 class,我创建了一个对象列表。
var TransactionList = new List<TransactionObject>();
我想获取 Unique ProjectsIdm OrgName 的列表以及基于 TrnDate 的分组依据的 EUR Trans、Local Trans 的总和。 示例:
ProjectId OrgName Trn Date EUR Trns Local Trns
543332 Organization 1 1-Jan-22 100 150
543332 Organization 1 1-Jan-22 150 20
我需要: 对不起,我的错误,我编辑了我需要的正确输出
ProjectId OrgName Trn Date EUR Trns Local Trns
543332 Organization 1 1-Jan-22 250 170
我尝试了什么:
List<TransactionObject> result = TransactionList .GroupBy (g => new {
g.HoldingName, g.TransactionValues.First().TrntDate })
.Select(g => g.First())
.ToList();
我试过了,但它对列的总和没有帮助,我擅长 Java 但 C# 新手请帮助我。我已经超过了这个对象的最后期限。
我认为将操作分为两个阶段可能会有所帮助。
var flattened = TransactionList
.SelectMany(
collectionSelector: o => o.Transactions,
resultSelector: (fullObject, transaction) => new { fullObject.ProjectId, fullObject.OrgName, Transaction = transaction });
var grouped = flattened
.GroupBy (t => new {t.ProjectId, t.OrgName, t.Transaction.TrnDate })
.Select( g => new
{
g.Key.ProjectId,
g.Key.OrgName,
g.Key.TrnDate,
SumEURTrans = g.Sum( t => t.Transaction.EURTrans),
SumLocaTrans = g.Sum( t => t.Transaction.LocaTrans)
})
.ToList();
foreach (var t in grouped)
{
Console.WriteLine($"{t.ProjectId}\t{t.OrgName}\t{t.TrnDate}\t{t.SumEURTrans}\t{t.SumLocaTrans}");
}
这会产生
543332 Organization 1 1-Jan-22 250 170
543332 Organization 1 2-Jan-22 450 470
543333 Organization 1 1-Jan-22 250 170
对于
的示例输入var TransactionList = new [] {
new TransactionObject
{
ProjectId = 543332,
OrgName = "Organization 1",
Transactions = new List<TransactionObject.TransactionValue>
{
new TransactionObject.TransactionValue
{
TrnDate = "1-Jan-22",
EURTrans = 100,
LocaTrans = 150
},
new TransactionObject.TransactionValue
{
TrnDate = "1-Jan-22",
EURTrans = 150,
LocaTrans = 20
}
,new TransactionObject.TransactionValue
{
TrnDate = "2-Jan-22",
EURTrans = 200,
LocaTrans = 250
},
new TransactionObject.TransactionValue
{
TrnDate = "2-Jan-22",
EURTrans = 250,
LocaTrans = 220
}
}
},
new TransactionObject
{
ProjectId = 543333,
OrgName = "Organization 1",
Transactions = new List<TransactionObject.TransactionValue>
{
new TransactionObject.TransactionValue
{
TrnDate = "1-Jan-22",
EURTrans = 100,
LocaTrans = 150
},
new TransactionObject.TransactionValue
{
TrnDate = "1-Jan-22",
EURTrans = 150,
LocaTrans = 20
}
}
}
};
这将按 {t.ProjectId, t.OrgName, t.Transaction.TrnDate}
对所有对象进行分组,您需要决定这是否是您想要的(一个示例替代方案是仅在每个 TransactionObject
中分组)。
如果我没理解错的话 - 你可以这样一次性完成 运行:
public void GroupTransactions(TransactionObject[] transactionObjects)
{
var results = transactionObjects
// build a flat list of values to have both transactionObject and value for every transactionValue
.SelectMany(obj => obj.TransactionValues.Select(value => (obj, value)))
.GroupBy(tuple => new {tuple.obj.ProjectId, tuple.obj.OrgName, tuple.value.TrnDate})
// Get sums for every group. You can use '.Aggregate()' method instead of this custom GetSum but it seems less readable to me.
.Select(group => (group.Key, sum: GetSum(group.Select(tuple => tuple.value))))
.ToArray();
foreach (var result in results)
Console.WriteLine($"{result.Key.ProjectId} {result.Key.OrgName} {result.Key.TrnDate} {result.sum.euro} {result.sum.local}");
}
private static (decimal euro, decimal local) GetSum(IEnumerable<TransactionObject.TransactionValue> values)
{
decimal euro = 0, local = 0;
foreach (var value in values)
{
euro += value.EURTrans;
local += value.LocaTrans;
}
return (euro, local);
}