user6703592
user6703592

Reputation: 1136

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?

Upvotes: 2

Views: 4374

Answers (1)

Gilad Green
Gilad Green

Reputation: 37299

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

Upvotes: 3

Related Questions