Menambahkan catatan ke kumpulan hasil melalui pernyataan dan perhitungan LINQ

Asumsikan saya memanggil titik akhir API dan mendapatkan kembali beberapa nilai tukar dalam bentuk DataTable. Saya kemudian memfilter nilai tukar tersebut menggunakan pernyataan LINQ untuk hanya mengembalikan nilai yang saya minati.

LINQ untuk memfilter nilai tukar:

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();

Pernyataan LINQ kembali:

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

Saya ingin menambahkan, pada catatan yang dihasilkan, nilai tukar timbal balik. Jadi jika saya memiliki nilai tukar USD ke GBP sebesar 88,45 saya ingin menambahkan rekor GBP ke USD sebesar 113,06. Jadi intinya saya menukar kolom OriginalCurrency dan TargetCurrency dan mengambil kebalikan dari rate pertama lalu mengalikannya dengan 10.000. Saya memiliki LINQ untuk memfilter catatan tetapi tidak tahu cara menyesuaikan pernyataan LINQ untuk menambahkan dua catatan nilai tukar timbal balik baru.

Pengembalian pernyataan LINQ yang diinginkan:

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

person webworm    schedule 03.04.2020    source sumber


Jawaban (2)


Anda dapat Select nilai tukar timbal balik menjadi yang baru dapat dihitung terlebih dahulu

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

Lalu Concat kedua hasil ke dalam daftar baru

var total = results.Concat(reciprocalResults).ToList();
person Pavel Anikhouski    schedule 03.04.2020
comment
Kamu hanya results = results.Concat(results.Select(...)) - person Magnus; 03.04.2020

Karena Anda ingin memetakan setiap item dalam urutan menjadi 2 item (tingkat dan kebalikannya), Anda harus menggunakan SelectMany.

Pertama, tulis metode yang, jika diberi satu baris dalam tabel, akan menghasilkan 2 baris:

// 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
    };
}

Lalu, panggil SelectMany di akhir rantai metode:

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

(Tentu saja, Anda bisa membuat RateAndReciprocal inline, yang akan menyelamatkan Anda dari pembuatan kelas ExchangeRate, tapi saya lebih suka ini)

person Sweeper    schedule 03.04.2020
comment
Sepertinya Anda lupa lalu kalikan dengan 10.000 :) - person Pavel Anikhouski; 03.04.2020
comment
@PavelAnikhouski Ups! Terima kasih! - person Sweeper; 03.04.2020