I have two lists. One list is of type Cascade (named, cascadeList) & the other list if of type PriceDetails (named priceList), both classes are shown below. I have also given a simple example of what I'm trying to achieve below the classes.
So the priceList contains a list of PriceDetail objects where they can be multiple (up to three) PriceDetail objects with the same ISIN. When there are multiple PriceDetails with the same ISIN I want to select just one based on the Source field.
This is where the cascadeList comes in. So if there were 3 PriceDetails with the same ISIN I would want to select the one where the source has the highest rank in the cascade list (1 is the highest). Hopefully the example below helps.
Reason for the question
I do have some code that is doing this for me however its not very efficient due to my lack of skill.
In a nutshell it first creates a unique list of ISIN's from the priceList. It then loops through this list for each unique ISIN to get a list of the PriceDetails with the same ISIN then uses some if statements to determine which object I want. So hoping and pretty sure there is a better way to do this.
My Classes
class Cascade
{
int Rank;
string Source;
}
class PriceDetails
{
string ISIN;
string Sedol;
double Price;
string Source;
}
Example
PriceList Cascade
ISIN Source Price Source Rank
BN1 XYZ 100 ABC 1
MGH PLJ 102 XYZ 2
BN1 PLJ 99.5 PLJ 3
BN1 ABC 98
MGH XYZ 102
Result I'm looking for
PriceList
ISIN Source Price
BN1 ABC 98
MGH XYZ 102
from pr in priceList
join c in cascadeList on pr.Source = c.Source
order by c.Rank
select new {Isin = pr.Isin, Source = pr.Source, Price = pr.Price}
For getting the desired result we must do these steps:
Source
property. ISIN
property. ISIN
. minRank
variable to compare it against the rank of an elements with the same ISIN
and then select the first element. We can write this query either with query or method syntax .
With query syntax:
var result = from pr in pricesList
join cas in cascadesList on pr.Source equals cas.Source
select new { pr, cas } into s
group s by new { s.pr.ISIN } into prcd
let minRank = prcd.Min(x => x.cas.Rank)
select prcd.First(y => y.cas.Rank == minRank).pr;
With method syntax:
var result = pricesList.Join(cascadesList,
pr => pr.Source,
cas => cas.Source,
(pr, cas) => new { pr, cas })
.GroupBy(j => j.pr.ISIN)
.Select(g => new { g, MinRank = g.Min(x => x.cas.Rank) })
.Select(r => r.g.First(x => x.cas.Rank == r.MinRank).pr);
Result will be same with both ways:
PriceList
ISIN Source Price
BN1 ABC 98
MGH XYZ 102
PS: I have assumed that list's name is as following: pricesList
and cascadesList
See if this works for you
priceList.GroupBy(p => p.ISIN).OrderByDescending(p =>
cascadeList.FirstOrDefault(c => c.Source == p.Source).Rank).First();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.