使用 VB.NET 2008 进行此分组的 Linq 代码是什么?

发布于 2024-10-27 16:34:46 字数 2077 浏览 1 评论 0原文

我的人口年龄从 0 岁到 119 岁。

我希望根据以下假设对 15 岁至 49 岁的人口进行分组:

  1. 15 岁至 19 岁;
  2. 20至24;
  3. 25 至 29;
  4. 30 至 34;
  5. 35 至 39;
  6. 40 至 44;
  7. 45 到 49。

无论年龄如何,这些对于我需要执行的计算都是无用的。以下是一些示例数据和代码。

我有一个 AnnualPopulation 类,它代表每一年的人口数量。

Public Class AnnualPopulation
    Public Id as Integer
    Public Year As Integer
    Public Gender As String
    Public YearsOfAge As Double?() = New Double?(119) { }
End Class

然后,YearsOfAge 数组/集合属性包含基于性别的人数。例如:

AnnualPopulation.Year = 2009
AnnualPopulation.Gender = "F"c
For age As Integer = 0 To AnnualPopulation.YearsOfAge.Length - 1 Step 1
    YearsOfAge(age) = 42356.67F 'Of course, this number varies from a years of age to another!'
Next

然后我想进行如下分组:

Dim groups() As Double = New Double(6) { }
For age As Integer = 15 To 49 Step 1
    Dim index As Integer = 0

    Select Case age
        Case 15 to 19
            index = 0
        Case 20 To 24
            index = 1
        Case 25 To 29
            index = 2
        Case 30 To 34
            index = 3
        Case 35 To 39
            index = 4
        Case 40 To 44
            index = 5
        Case 45 To 49
            index = 6
    End Select

    groups(index) += AnnualPopulation.YearsOfAge(age - 1)
Next

这样,我就可以得到每个年龄范围的人口总和

所以,我想对它们进行分组,然后我没有共同的密钥来对它们进行分组,运气不好! =P 在 C# 中,我想这可以满足我的需要:

double[] groups = new double[7];
Enumerable.Range(15, 34).ToList().ForEach(age => {
    groups[(int)(age % 4)] += annualPopulation.YearsOfAge[age - 1].HasValue 
                              ? annualPopulation.YearsOfAge[age - 1].Value : 0.0;
});

除非我尝试使用 New Action(Of T1, T2)<,否则我似乎无法在 VB.NET 2008 中实现这一点/code> 或 Func(Of Double?, TKey)。我对这些一点都不舒服! =( (潜在问题:为什么在 VB.NET 中使用 lambda 如此复杂!?)

我的代码实际上可以工作,我只是在寻找一个更好、也许更易读的解决方案,尽管这个很容易理解我在这里想要实现的目标。

无论如何,有人知道如何进行此操作吗?

=)

I have a population aged from 0 to 119 years.

I wish to group this population from the age of 15 to 49 according to the following hypothesis:

  1. 15 to 19;
  2. 20 to 24;
  3. 25 to 29;
  4. 30 to 34;
  5. 35 to 39;
  6. 40 to 44;
  7. 45 to 49.

Any age apart these are useless for the calculation I need to perform. Here are some sample data and code.

I have an AnnualPopulation class which represents the demographic population for each year of age.

Public Class AnnualPopulation
    Public Id as Integer
    Public Year As Integer
    Public Gender As String
    Public YearsOfAge As Double?() = New Double?(119) { }
End Class

Then, the YearsOfAge array/collection property contains the number of people based on their gender. For instance:

AnnualPopulation.Year = 2009
AnnualPopulation.Gender = "F"c
For age As Integer = 0 To AnnualPopulation.YearsOfAge.Length - 1 Step 1
    YearsOfAge(age) = 42356.67F 'Of course, this number varies from a years of age to another!'
Next

I would then like to group such as follows:

Dim groups() As Double = New Double(6) { }
For age As Integer = 15 To 49 Step 1
    Dim index As Integer = 0

    Select Case age
        Case 15 to 19
            index = 0
        Case 20 To 24
            index = 1
        Case 25 To 29
            index = 2
        Case 30 To 34
            index = 3
        Case 35 To 39
            index = 4
        Case 40 To 44
            index = 5
        Case 45 To 49
            index = 6
    End Select

    groups(index) += AnnualPopulation.YearsOfAge(age - 1)
Next

This way, I would have the sum of population for each range of year of age

So, I though of grouping them, and then I have no common key to group them by, no luck! =P In C#, I guess this would do what I need:

double[] groups = new double[7];
Enumerable.Range(15, 34).ToList().ForEach(age => {
    groups[(int)(age % 4)] += annualPopulation.YearsOfAge[age - 1].HasValue 
                              ? annualPopulation.YearsOfAge[age - 1].Value : 0.0;
});

Which I don't seem to be able to achieve in VB.NET 2008 except if I try to go along with New Action(Of T1, T2) or else Func(Of Double?, TKey). I'm not comfortable at all with these! =( (Underlying question: Why is it so complicated in VB.NET to work with lambdas!?)

My code actually works, I'm only looking for a nicer and perhaps more readable solution, though this is easy to understand what I'm trying to achieve here.

Anyway, anyone has a clue about how to go with this?

Thanks in advance! =)

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

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

发布评论

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

评论(1

潜移默化 2024-11-03 16:34:46

在 group by 选择器中使用 switch 语句;则按键将分别为 0 至 6。之后,您只需对每个组使用 Sum 运算符即可。

在 C# 中,它看起来像这样(在 C# 中没有范围 case):

var filtered = data
    .Where(item => item.Age > 15 && item.Age <= 49)
    .GroupBy(item => 
                    {
                     if(item.Age > 15 && item.Age <= 19)
                       return 0;
                     else if(item.Age <= 24)
                       return 1;
                     else if(item.Age <= 29)
                       return 2;
                     else if(item.Age <= 34)
                       return 3;
                     else if(item.Age <= 39)
                       return 4;
                     else if(item.Age <= 44)
                       return 5;
                     else if(item.Age <= 49)
                       return 6;
                    });

之后,您可以创建一个字典:

var dict = filtered.ToDictionary(i => i.Key, i => /* do something with the sequence */);

Use your switch statement in the group by selector; the keys will be 0 to 6 respectively then. After that, you simply can use the Sum operator on each group.

In C#, it would look like this (you don't have ranged cases in C#):

var filtered = data
    .Where(item => item.Age > 15 && item.Age <= 49)
    .GroupBy(item => 
                    {
                     if(item.Age > 15 && item.Age <= 19)
                       return 0;
                     else if(item.Age <= 24)
                       return 1;
                     else if(item.Age <= 29)
                       return 2;
                     else if(item.Age <= 34)
                       return 3;
                     else if(item.Age <= 39)
                       return 4;
                     else if(item.Age <= 44)
                       return 5;
                     else if(item.Age <= 49)
                       return 6;
                    });

After that, you can create a dictionary:

var dict = filtered.ToDictionary(i => i.Key, i => /* do something with the sequence */);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文