在 LINQ 中将两个查询转换为一个查询
Transforming two queries into one query in LINQ
我正在计算每个 Pair
来自 List<BacktestResult>
的利润及其交易数量,以及 BacktestResult
对象本身,因为我需要它的属性,例如.打印它们。这就是下面的 foreach
所做的。然后我要接收最大利润的对象。该代码按预期工作,但我想完全在 LINQ 中重新创建它,例如。没有那个丑陋的 Max() 检查。应该 return var bestPair = BacktestResult object of the maximum result.Sum(e => e.ProfitPercentage)
.
(decimal Max, string Pair) value = (int.MinValue, null);
foreach (var result in data.GroupBy(e => e.Pair)
.Select(e => new { Pair = e.Key, Count = e.Count(), Value = e }))
{
var profitSum = result.Value.Sum(e => e.ProfitPercentage);
if (profitSum > value.Max)
{
value.Max = profitSum;
value.Pair = result.Pair;
}
}
public class BacktestResult
{
public string Pair { get; set; }
public decimal ProfitPercentage { get; set; }
public decimal ProfitAbs { get; set; }
public decimal OpenRate { get; set; }
public decimal CloseRate { get; set; }
public DateTime OpenDate { get; set; }
public DateTime CloseDate { get; set; }
public decimal OpenFee { get; set; }
public decimal CloseFee { get; set; }
public decimal Amount { get; set; }
public decimal TradeDuration { get; set; }
public SellType SellReason { get; set; }
}
public static class LinqExtensions
{
public static T MaxBy<T, R>(this IEnumerable<T> en, Func<T, R> evaluate) where R : IComparable<R>
{
return en.Select(t => new Tuple<T, R>(t, evaluate(t)))
.Aggregate((max, next) => next.Item2.CompareTo(max.Item2) > 0 ? next : max).Item1;
}
public static T MinBy<T, R>(this IEnumerable<T> en, Func<T, R> evaluate) where R : IComparable<R>
{
return en.Select(t => new Tuple<T, R>(t, evaluate(t)))
.Aggregate((max, next) => next.Item2.CompareTo(max.Item2) < 0 ? next : max).Item1;
}
}
你可以试试
string pairOfGroupWithHighestProfitSum = data.GroupBy(e => e.Pair).
Select(e => new { Pair = e.Key, Count = e.Count(), ProfitSum = e.Sum(e => e.ProfitPercentage), Value = e }).
OrderByDescending(e => e.ProfitSum).
FirstOrDefault()?.Pair;
如果你的data
为空,则为null,否则你将获得利润总额最高的组对。
如果您使用 .NET Core,您不会通过先排序然后取第一个值来查找最大值来获得性能损失。参见 https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/orderby-firstordefault-complexity-increase
我正在计算每个 Pair
来自 List<BacktestResult>
的利润及其交易数量,以及 BacktestResult
对象本身,因为我需要它的属性,例如.打印它们。这就是下面的 foreach
所做的。然后我要接收最大利润的对象。该代码按预期工作,但我想完全在 LINQ 中重新创建它,例如。没有那个丑陋的 Max() 检查。应该 return var bestPair = BacktestResult object of the maximum result.Sum(e => e.ProfitPercentage)
.
(decimal Max, string Pair) value = (int.MinValue, null);
foreach (var result in data.GroupBy(e => e.Pair)
.Select(e => new { Pair = e.Key, Count = e.Count(), Value = e }))
{
var profitSum = result.Value.Sum(e => e.ProfitPercentage);
if (profitSum > value.Max)
{
value.Max = profitSum;
value.Pair = result.Pair;
}
}
public class BacktestResult
{
public string Pair { get; set; }
public decimal ProfitPercentage { get; set; }
public decimal ProfitAbs { get; set; }
public decimal OpenRate { get; set; }
public decimal CloseRate { get; set; }
public DateTime OpenDate { get; set; }
public DateTime CloseDate { get; set; }
public decimal OpenFee { get; set; }
public decimal CloseFee { get; set; }
public decimal Amount { get; set; }
public decimal TradeDuration { get; set; }
public SellType SellReason { get; set; }
}
public static class LinqExtensions
{
public static T MaxBy<T, R>(this IEnumerable<T> en, Func<T, R> evaluate) where R : IComparable<R>
{
return en.Select(t => new Tuple<T, R>(t, evaluate(t)))
.Aggregate((max, next) => next.Item2.CompareTo(max.Item2) > 0 ? next : max).Item1;
}
public static T MinBy<T, R>(this IEnumerable<T> en, Func<T, R> evaluate) where R : IComparable<R>
{
return en.Select(t => new Tuple<T, R>(t, evaluate(t)))
.Aggregate((max, next) => next.Item2.CompareTo(max.Item2) < 0 ? next : max).Item1;
}
}
你可以试试
string pairOfGroupWithHighestProfitSum = data.GroupBy(e => e.Pair).
Select(e => new { Pair = e.Key, Count = e.Count(), ProfitSum = e.Sum(e => e.ProfitPercentage), Value = e }).
OrderByDescending(e => e.ProfitSum).
FirstOrDefault()?.Pair;
如果你的data
为空,则为null,否则你将获得利润总额最高的组对。
如果您使用 .NET Core,您不会通过先排序然后取第一个值来查找最大值来获得性能损失。参见 https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/orderby-firstordefault-complexity-increase