user6703592 user6703592 - 3 years ago 197
C# Question

C# LINQ filter the List of tuple with given List

Here is

pariList
(it's
List of Tuple
)

List<Tuple<dynamic, dynamic>> PairList = new List<Tuple<dynamic, dynamic>> =
{({ Symbol = a, Close = 1.0, Date = 2/1/2016, Vol = 0 }, { Symbol = b, Close = 1.6, Date = 2/1/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.0, Date = 2/1/2016, Vol = 0 }, { Symbol = c, Close = 2.0, Date = 2/1/2016 , Vol = 0 })}
{({ Symbol = b, Close = 1.6, Date = 2/1/2016, Vol = 0 }, { Symbol = c, Close = 2.0, Date = 2/1/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.1, Date = 2/2/2016, Vol = 0 }, { Symbol = b, Close = 1.2, Date = 2/2/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.1, Date = 2/2/2016, Vol = 0 }, { Symbol = c, Close = 2.1, Date = 2/2/2016, Vol = 0 })}
{({ Symbol = b, Close = 1.2, Date = 2/2/2016, Vol = 0 }, { Symbol = c, Close = 2.1, Date = 2/2/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.4, Date = 2/3/2016, Vol = 0 }, { Symbol = b, Close = 1.4, Date = 2/3/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.4, Date = 2/3/2016, Vol = 0 }, { Symbol = c, Close = 1.4, Date = 2/3/2016, Vol = 0 })}
{({ Symbol = b, Close = 1.4, Date = 2/3/2016, Vol = 0 }, { Symbol = c, Close = 1.4, Date = 2/3/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.7, Date = 2/4/2016, Vol = 0.214285714285714 }, { Symbol = b, Close = 1.8, Date = 2/4/2016, Vol = 0.218217890235992 })}
{({ Symbol = a, Close = 1.7, Date = 2/4/2016, Vol = 0.214285714285714 }, { Symbol = c, Close = 2.7, Date = 2/4/2016, Vol = 0.464743364189122 })}
{({ Symbol = b, Close = 1.8, Date = 2/4/2016, Vol = 0.218217890235992 }, { Symbol = c, Close = 2.7, Date = 2/4/2016, Vol = 0.464743364189122 })}
{({ Symbol = a, Close = 1.8, Date = 2/5/2016, Vol = 0.122450941145067 }, { Symbol = b, Close = 1.2, Date = 2/5/2016, Vol = 0.169725025739105 })}
{({ Symbol = a, Close = 1.8, Date = 2/5/2016, Vol = 0.122450941145067 }, { Symbol = c, Close = 1.2, Date = 2/5/2016, Vol = 0.301649178342484 })}
{({ Symbol = b, Close = 1.2, Date = 2/5/2016, Vol = 0.169725025739105 }, { Symbol = c, Close = 1.2, Date = 2/5/2016, Vol = 0.301649178342484 })}
......
......


And now, I select some pairs at a special date

var wantedCombinations = pairList
.Where(pair => pair.Item1.Date == Beginday)
.Select(pair => new { Item = pair, Volspread = Math.Abs(pair.Item1.Vol - pair.Item2.Vol) })
.OrderBy(o => o.Volspread)
.Take(FirstSelect)
.Select(item =>item.Item)
.ToList();


Then how to make the 'pairList' only left those selected pairs in
wantedCombinations
every date. e.g

select
{a, b}, {a, c}
, then
pairList
become

{({ Symbol = a, Close = 1.0, Date = 2/1/2016, Vol = 0 }, { Symbol = b, Close = 1.6, Date = 2/1/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.0, Date = 2/1/2016, Vol = 0 }, { Symbol = c, Close = 2.0, Date = 2/1/2016 , Vol = 0 })}
{({ Symbol = a, Close = 1.1, Date = 2/2/2016, Vol = 0 }, { Symbol = b, Close = 1.2, Date = 2/2/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.1, Date = 2/2/2016, Vol = 0 }, { Symbol = c, Close = 2.1, Date = 2/2/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.4, Date = 2/3/2016, Vol = 0 }, { Symbol = b, Close = 1.4, Date = 2/3/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.4, Date = 2/3/2016, Vol = 0 }, { Symbol = c, Close = 1.4, Date = 2/3/2016, Vol = 0 })}
{({ Symbol = a, Close = 1.7, Date = 2/4/2016, Vol = 0.214285714285714 }, { Symbol = b, Close = 1.8, Date = 2/4/2016, Vol = 0.218217890235992 })}
{({ Symbol = a, Close = 1.7, Date = 2/4/2016, Vol = 0.214285714285714 }, { Symbol = c, Close = 2.7, Date = 2/4/2016, Vol = 0.464743364189122 })}
{({ Symbol = a, Close = 1.8, Date = 2/5/2016, Vol = 0.122450941145067 }, { Symbol = b, Close = 1.2, Date = 2/5/2016, Vol = 0.169725025739105 })}
{({ Symbol = a, Close = 1.8, Date = 2/5/2016, Vol = 0.122450941145067 }, { Symbol = c, Close = 1.2, Date = 2/5/2016, Vol = 0.301649178342484 })}
......
......


And it is better to achieve those two steps in one Linq query?

Answer Source

After much talk in the chat this is the answer:

var wantedCombinations = pairList.Where(pair => pair.Item1.Date == Beginday)
                                 .Select(pair => new { Item = pair,  Volspread = Math.Abs(pair.Item1.Vol - pair.Item2.Vol) })
                                 .OrderBy(o => o.Volspread)
                                 .Take(FirstSelect)
                                 .Select(item =>item.Item);

pairList = pairList.Where(pair => 
                        wantedCompinations.Any(wc => wc.Item1.Symbol == pair.Item1.Symbol &&
                                                     wc.Item2.Symbol == pair.Item2.Symbol)).ToList();

In order to keep only pairs that have the symbols in Item1 and Item2 like you described add to the Where also a check that the current pair is in the options list:

var wantedCombinations = new List<dynamic>
{
    new { Symbol1 = "a", Symbol2 = "b" },
    new { Symbol1 = "a", Symbol2 = "c" }
};

var result = pairList.Where(pair => pair.Item1.Date == Beginday &&
                                    wantedCombinations.Any(item => item.Symbol1 == pair.Item1.Symbol &&
                                                      item.Symbol2 == pair.Item2.Symbol))
                     .Select(pair => new { Item = pair, Volspread = Math.Abs(pair.Item1.Vol - pair.Item2.Vol) })
                     .OrderBy(o => o.Volspread)
                     .Take(FirstSelect)
                     .Select(item =>item.Item)
                     .ToList();

Another way can be to join the two lists:

var wantedCombinations = new List<dynamic>
{
    new { Symbol1 = "a", Symbol2 = "b" },
    new { Symbol1 = "a", Symbol2 = "c" }
};

var result = (from pair in pairList
             where pait.Item1.Date.Equals(Beginday)
             join c in wantedCombinations on new { pair.Item1.Symbol, pair.Item2.Symbol } equls new { c.Symbol1, c.Symbol2 }
             orderby Math.Abs(pair.Item1.Vol - pair.Item2.Vol)
             select pair).Take(FirstSelect);

In anycase if you decide going to the query syntax rather than the method syntax (doesn't matter if you prefer the .Any or join options) you can then orderby without having to add that extra Select

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download