LINQ组由任意格子组合

dar*_*pbj 4 c# linq

如果我遗漏了一些非常基本的东西,请道歉.

对于给定的晶格数组,其中晶格值代表其桶的最小值,对值数组进行分组的最佳方法是什么.

例如

double[] lattice = { 2.3, 2.8, 4.1, 4.7 };
double[] values  = { 2.35, 2.4, 2.6, 3, 3.8, 4.5, 5.0, 8.1 };

GroupByLattice(values, lattice);
Run Code Online (Sandbox Code Playgroud)

这样GroupByLattice返回如下所示的IGroupings:

2.3 : { 2.35, 2.4, 2.6 }
2.8 : { 3, 3.8 }
4.1 : { 4.5 }
4.7 : { 5.0, 8.1 }
Run Code Online (Sandbox Code Playgroud)

编辑:

我对LINQ查询非常环保,这是我能做到的最好的:

values.GroupBy( curr => lattice.First( lat => curr > lat) )
Run Code Online (Sandbox Code Playgroud)

问题:

  • 一切都在第一桶中结束 - 我可以理解为什么(当然第一个桶满足每个后面的情况)但是我很难绕过这些就地操作以获得我真正想要的谓词.
  • 我怀疑在LINQ查询中有一个LINQ查询将不是非常高效

死后解决方案和结果:

德米特里·拜琴科提供了一个很好的答案,我只是想为将来可能会遇到这个答案的人提供一些跟进.我原本试图解决:如何简化绘图的庞大数据集?

对于初学者来说,我的第一次尝试实际上非常接近.由于我的格子已经订购,我只需.First( ... )要将a 更改为a.Last( ... )

    values.GroupBy( curr => lattice.Last( lat => curr > lat) )
Run Code Online (Sandbox Code Playgroud)

这一切都很好,但很好奇Dmitry的解决方案会有多好.我用随机的10000个双打测试它,格子间距为0.25.(我.Select(...)从德米特里的解决方案中剔除了转变以保持公平)

20次运行的平均值吐出结果:

Mine: 602ms
Dmitrys: 3ms
Run Code Online (Sandbox Code Playgroud)

呃......哇!这是速度提高200倍.200X!我不得不运行这几次并在调试器中检查以确定LINQ语句在时间戳之前进行评估(Trusty .ToArray()to the rescue).我现在要说的是,任何想要完成同样任务的人都应该使用这种方法

Dmi*_*nko 5

提供lattice排序(可以很容易地对数组进行排序Array.Sort(lattice)),您可以使用Array.BinarySearch:

  double[] lattice = { 2.3, 2.8, 4.1, 4.7 };
  double[] values = { 2.35, 2.4, 2.6, 3, 3.8, 4.5, 5.0, 8.1 };

  var result = values
    .GroupBy(item => {
      int index = Array.BinarySearch(lattice, item);

      return index >= 0 ? lattice[index] : lattice[~index - 1];
    })
    .Select(chunk => String.Format("{0} : [{1}]", 
       chunk.Key, String.Join(", ", chunk)));
Run Code Online (Sandbox Code Playgroud)

测试

  Console.Write(String.Join(Environment.NewLine, result));
Run Code Online (Sandbox Code Playgroud)

结果

  2.3 : [2.35, 2.4, 2.6]
  2.8 : [3, 3.8]
  4.1 : [4.5]
  4.7 : [5, 8.1] 
Run Code Online (Sandbox Code Playgroud)