编辑到最后以获取对第二个代码块的解释和一个以粗体显示的重要免责声明。
var query = from acct in accts
select new
{
acct.From,
acct.To,
acct.Amount,
FirstOrientedAmount = ((acct.From.CompareTo(acct.To) == -1 && acct.Amount < 0) ||
(acct.From.CompareTo(acct.To) >= 0 && acct.Amount > 0)) ? acct.Amount : 0,
SecondOrientedAmount = ((acct.From.CompareTo(acct.To) >= 0 && acct.Amount < 0) ||
(acct.From.CompareTo(acct.To) == -1 && acct.Amount > 0)) ? acct.Amount * -1 : 0
} into r
group r by new
{
First = (r.From.CompareTo(r.To) == -1 ? r.From : r.To),
Second = (r.From.CompareTo(r.To) == -1 ? r.To : r.From)
} into g
select new
{
First = g.Sum(acctval => acctval.FirstOrientedAmount) + g.Sum(acctval => acctval.SecondOrientedAmount) > 0 ? g.Key.Second : g.Key.First,
Second = g.Sum(acctval => acctval.FirstOrientedAmount) + g.Sum(acctval => acctval.SecondOrientedAmount) > 0 ? g.Key.First : g.Key.Second,
FTotal = g.Sum(acctval => acctval.FirstOrientedAmount),
STotal = g.Sum(acctval => acctval.SecondOrientedAmount),
Total = g.Sum(acctval => acctval.FirstOrientedAmount) + g.Sum(acctval => acctval.SecondOrientedAmount),
};
这给出了:
CAD USD -150
GBP AUD 500
编辑:我放弃了旧代码,因为我不完全理解这些要求,但我发布了一些不依赖编译器来优化它的东西:
var query = from p in accts
select new
{
p.From,
p.To,
p.Amount,
OrientedAmount = ((p.From.CompareTo(p.To) == -1 && p.Amount < 0) ||
(p.From.CompareTo(p.To) >= 0 && p.Amount > 0)) ? p.Amount : p.Amount * -1
} into r
group r by new
{
First = (r.From.CompareTo(r.To) == -1 ? r.From : r.To),
Second = (r.From.CompareTo(r.To) == -1 ? r.To : r.From)
} into g
select new
{
g.Key.First,
g.Key.Second,
Total = g.Sum(val => val.OrientedAmount)
} into last
select new
{
First = last.Total > 0 ? last.Second : last.First,
Second = last.Total > 0 ? last.First : last.Second,
Total = last.Total
};
这通过首先将所有金额定向到其 From 帐户是最大的按字典顺序排列的货币名称的交易来工作。如果当前交易行实际上将资金转移到字典上最小的货币名称,则翻转金额上的符号。
现在通过按字典顺序对交易中的帐户进行分组。
选择总数(这样我们只需执行一次)。为此,请添加所有定向数量。
如果总值是正数(我这样做的方式),我们有一个净值进入最大的按字典顺序排列的货币名称。如果它是负数,则净值将进入按字典顺序排列的最小货币名称。
但是,我不相信这些是好的要求(或者我误解了最初的要求)。如果你看这个问题是解决什么问题,它将“AB 卖出”、“AB 买入”、“BA 买入”和“BA 卖出”组合为一组。在这种情况下,“AB 100”表示“AB -100”。第一个意味着买 100 个 A。第二个意味着把 100 个 B 卖给 A。如果你看一下这个问题的解决方式, 它们是一回事。 但实际上, 它们不是一回事。 卖 100 B 不会给你和买 100 A 一样多的 A。您需要汇率来使其正常化。