选择具有组&min;最小值的组的所有元素

时间:2016-08-16 08:17:06

标签: c# linq

这是表格

 Tuple<dynamic, dynamic> pair = new 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 })}
  ......
  ......

我希望在&#39; 2016年2月3日之后每天选择Vol(min | Vol1 - Vol2 |)的最小摘要对(前一个日期可以是默认值) 预期形式如下:

  {({ Symbol = a, Close = 1.7, Date = 2/4/2016, Vol = 0.214285714285714 }, { Symbol = b, Close = 1.8, Date = 2/4/2016, Vol = 0.218217890235992 }), Volspread = XXXX}
  {({ Symbol = b, Close = 1.2, Date = 2/5/2016, Vol = 0.169725025739105 }, { Symbol = c, Close = 1.2, Date = 2/5/2016, Vol = 0.301649178342484 }), Volspread = XXXX}
  ....... 
  .......

这里Volspread分别只是最小值。

2 个答案:

答案 0 :(得分:1)

选择每组中min差异的项目:

var result = pairs
    .Where(pair => pair.Item1.Date > new DateTime(2016, 2, 3))
    .Select(pair => new { Item = pair, Diff = Math.Abs(pair.Item1.Vol - pair.Item2.Vol) })
    .GroupBy(pair => pair.Item.Item1.Date)
    .SelectMany(group => group.Where(item => item.Diff.Equals(group.Min(i => i.Diff))).Select(item => item.Item))
    .ToList();

测试数据:

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

编辑前:

你可以这样做:

//Remove irrelevant records and calculate diff
var result = pairs
    .Where(item => item.Item1.Date > new DateTime(2016, 2, 3))
    .Select(item => new { Item = item, Diff = Math.Abs(item.Item1.Vol - item.Item2.Vol) });

//Find min diff
var minDiff = result.Min(item => item.Diff);

//Get only records with min diff
result = result.Where(item => item.Diff.Equals(minDiff)).ToList();

另一种选择是将MoreLinq的nuget库用于MinBy

答案 1 :(得分:0)

查看MoreLinq MinBy。这正是您所需要的:

allPairs.GroupBy( x => x.first.Date.Date ).Select( x => x.MinBy( y => Math.Abs( y.first.Vol - y.second.Vol ) ) );

不保证语法错误; - )