vb.netlambda表达式选择下限值和上限值之间的所有值加上下一个下限值和上限值

发布于 2024-10-03 13:40:02 字数 328 浏览 1 评论 0原文

我需要 lamda 表达式的一些帮助来获取值范围的子集。我有一个较低和较高的值,并且获得它们之间的所有内容似乎很容易,但我还需要包含下一个较低和较高的值。我可以单独完成其中每一项,但如果可能的话,我希望一次完成。

我需要子集的范围有 150 个值。一个小例子如下: {8.206,8.206,8.201,8.196,8.193,8.192,8.189,8.174,8.171,8.171,8.166,8.163,8.157,8.154,8.153,8.14,8.131}

我的较低值是:8.16 我的上限值是:8.17

我需要返回:{8.171,8.171,8.166,8.163,8.157}

I need some help with a lamda expression to get a subset of range of values. I have a lower and upper value, and getting everything between them seems easy enough, but I also need the next lower and higher value to be included. I can do each of these seperately, but would like to do it in one shot if possible.

The range I need the subset from has 150 values. A small example would look like:
{8.206,8.206,8.201,8.196,8.193,8.192,8.189,8.174,8.171,8.171,8.166,8.163,8.157,8.154,8.153,8.14,8.131}

My lower value is: 8.16
My upper value is: 8.17

I need to get back: {8.171,8.171,8.166,8.163,8.157}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撩起发的微风 2024-10-10 13:40:02

在 C# 中,但也有类似的 VB 等效项。像这样的东西应该可以工作(未经测试)

……

enum RangeRelation {Below, InRange, Above};

如果对结果是否会被

mySetOfNumbers    
.Select(number =>
  new {
    Number = number,
    RangeRelation = 
             number < lowerBound ? RangeRelation.Below : 
             number > upperBound ? RangeRelation.Above :
             RangeRelation.InRange
  })
  .GroupBy(x=>x.RangeRelation)
  .SelectMany(group =>
    group.Key == RangeRelation.Below ?  
       ( group.Any() ? new [] { group.OrderBy(x=>x).Last() } : new double[0] ) :
    group.Key == RangeRelation.Above ? 
       ( group.Any() ? new [] { group.OrderBy(x=>x).First() } : new double[0] ) :
    group
  );

完全枚举有疑问,那没关系,因为延迟执行可能对你有利;但是,如果您确实使用了所有结果值,我怀疑这是否会被编译为有效的东西。

也就是说,GroupBy() 必须遍历集合一次,需要创建新类型,然后 OrderBy() 将类似于高于和低于范围值的O(n*log n)时间。这与这样的事情相反:

double? above = null;
double? below = null;
var selected = new List<double>();
foreach(var number in mySetOfNumbers)
  if(number < lowerBound && number > below??Double.MinValue)
   below = number;
  else if(number > upperBound && number < above??Double.MaxValue)
   above = number;
  else
   selected.Add(number);

if(above != null) selected.Add(above);
if(below != null) selected.Add(below);

return selected;

只需要一个枚举。

话虽这么说...对于 150 个值优化根本不重要。

In C# but there is a similar VB equivalent. Something like this should work (untested):

...

enum RangeRelation {Below, InRange, Above};

...

mySetOfNumbers    
.Select(number =>
  new {
    Number = number,
    RangeRelation = 
             number < lowerBound ? RangeRelation.Below : 
             number > upperBound ? RangeRelation.Above :
             RangeRelation.InRange
  })
  .GroupBy(x=>x.RangeRelation)
  .SelectMany(group =>
    group.Key == RangeRelation.Below ?  
       ( group.Any() ? new [] { group.OrderBy(x=>x).Last() } : new double[0] ) :
    group.Key == RangeRelation.Above ? 
       ( group.Any() ? new [] { group.OrderBy(x=>x).First() } : new double[0] ) :
    group
  );

It's ok if there is some question over whether the results will ever be fully enumerated since the delayed execution might work in your favor; however, if you are definitely using all of the resulting values I doubt that this will be compiled to something efficient.

That is to say, the GroupBy() has to traverse the set once, the new type needs to be created, and then the OrderBy() is going to be something like O(n*log n) time for both the Above and Below range values. This is as opposed to something like this:

double? above = null;
double? below = null;
var selected = new List<double>();
foreach(var number in mySetOfNumbers)
  if(number < lowerBound && number > below??Double.MinValue)
   below = number;
  else if(number > upperBound && number < above??Double.MaxValue)
   above = number;
  else
   selected.Add(number);

if(above != null) selected.Add(above);
if(below != null) selected.Add(below);

return selected;

Which only requires a single enumeration.

That being said...for 150 values optimization doesn't matter at all.

生生漫 2024-10-10 13:40:02

我最终做了这样的事情:

Dim myData As New List(Of someData) 
myData = sorceData.Where(Function(i) i.somevalue >= myLowervalue And i.somevalue <= myUpperValue).ToList 
myData = myData.Concat(sorceData.Where(Function(i) i.somevalue > myUpperValue).Take(1).ToList).ToList 
myData = myData.Concat(sorceData.Where(Function(i) i.somevalue < myLowervalue ).Take(1).ToList).ToList 

这不是一个单一的表达式,但它有效。

I ended up doing something like this:

Dim myData As New List(Of someData) 
myData = sorceData.Where(Function(i) i.somevalue >= myLowervalue And i.somevalue <= myUpperValue).ToList 
myData = myData.Concat(sorceData.Where(Function(i) i.somevalue > myUpperValue).Take(1).ToList).ToList 
myData = myData.Concat(sorceData.Where(Function(i) i.somevalue < myLowervalue ).Take(1).ToList).ToList 

It's not a single expression, but it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文