【问题标题】:Adding records to a result set via a LINQ statement and calculation通过 LINQ 语句和计算将记录添加到结果集中
【发布时间】:2020-04-03 13:26:50
【问题描述】:

假设我正在调用 API 端点并以 DataTable 的形式获取一些汇率。然后我使用 LINQ 语句过滤这些汇率,只返回我感兴趣的汇率。

用于过滤汇率的 LINQ:

var results = exchangeRates.Rows.Cast<DataRow>()
.Where(r => r.Field<double>("Rate") > 0)
.Where(r => r.Field<string>("FromCurrency").ToUpper() == "USD")
.Select(y => new
{
    FromCurrency = y.Field<string>("FromCurrency"),
    ToCurrency = y.Field<string>("ToCurrency"),
    ExchangeRate = y.Field<double>("Rate")
}).ToList();

LINQ 语句返回:

+------------------+----------------+---------+
| OriginalCurrency | TargetCurrency |   Rate  |
+------------------+----------------+---------+
|        USD       |       GBP      |  88.452 |
+------------------+----------------+---------+
|        USD       |       CAD      | 132.819 |
+------------------+----------------+---------+

我想在结果记录中添加互惠汇率。因此,如果我的美元兑英镑汇率为 88.45,我想添加一条英镑兑美元汇率为 113.06 的记录。所以基本上我交换 OriginalCurrency 和 TargetCurrency 列,取第一个汇率的倒数,然后乘以 10,000。我有 LINQ 来过滤记录,但不知道如何调整 LINQ 语句以添加两个新的相互汇率记录。

所需的 LINQ 语句返回:

+------------------+----------------+--------+
| OriginalCurrency | TargetCurrency |  Rate  |
+------------------+----------------+--------+
|        USD       |       GBP      |  88.45 |
+------------------+----------------+--------+
|        USD       |       CAD      | 132.81 |
+------------------+----------------+--------+
|        GBP       |       USD      | 113.06 |
+------------------+----------------+--------+
|        CAD       |       USD      |  75.30 |
+------------------+----------------+--------+

【问题讨论】:

    标签: c# linq datatable


    【解决方案1】:

    您可以将Select的互惠汇率换成新的可枚举第一

    var reciprocalResults = results
        .Select(y => new
        {
            FromCurrency = y.ToCurrency,
            ToCurrency = y.FromCurrency ,
            ExchangeRate = Math.Round (10000 / y.ExchangeRate, 2)
        });
    

    然后Concat 两个结果都进入新列表

    var total = results.Concat(reciprocalResults).ToList();
    

    【讨论】:

    • 你只是results = results.Concat(results.Select(...))
    【解决方案2】:

    由于您要将序列中的每个项目映射为 2 个项目(比率和倒数),您应该使用SelectMany

    首先,编写一个方法,给定表中的一行,返回 2 行:

    // Create a class called ExchangeRate, with the three properties in your anonymous object
    private static IEnumerable<ExchangeRate> RateAndReciprocal(ExchangeRate rate) {
        yield return rate;
        yield return new ExchangeRate {
            FromCurrency = rate.ToCurrency,
            ToCurrency = rate.FromCurrency,
            ExchangeRate = 10000 / rate.ExchangeRate
        };
    }
    

    然后,在方法链的末尾调用SelectMany

    .Select(y => new ExchangeRate
    {
        FromCurrency = y.Field<string>("FromCurrency"),
        ToCurrency = y.Field<string>("ToCurrency"),
        ExchangeRate = y.Field<double>("Rate")
    })
    .SelectMany(RateAndReciprocal)
    .ToList();
    

    (当然,您可以将RateAndReciprocal 内联,这样您就不用创建ExchangeRate 类,但我更喜欢这个)

    【讨论】:

    • 看来,你忘了然后乘以10,000 :)
    • @PavelAnikhouski 哎呀!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 2017-08-04
    相关资源
    最近更新 更多