【问题标题】:Array cumulative in order descending数组按降序累积
【发布时间】:2022-06-15 14:10:21
【问题描述】:

我正在尝试累积数组的值,按 column14 的 ID 分组。

我的代码如下所示:

Dim chartValues = New Dictionary(Of String, Decimal)()

For Each row In DataGridView1.Rows.OfType(Of DataGridViewRow)
    Dim column14Value = row.Cells().Item("Column14").Value.ToString()
    Dim column11Value = row.Cells().Item("Column11").Value

    If (chartValues.ContainsKey(column14Value)) Then
        chartValues(column14Value) = chartValues(column14Value) + column11Value
    Else
        chartValues.Add(column14Value, column11Value)
    End If
Next

For Each chartValue In chartValues
    Dim Tot As Decimal
    Tot += chartValue.Value
    ComboBox1.Items.Add(Tot)
Next

我的问题是数组中值的顺序是无序的,我需要对它进行降序排序(对于帕累托),但我不知道该怎么做。 (由它自己累积它那些工作) 非常感谢任何帮助。谢谢!

【问题讨论】:

  • 那里没有数组。那是DictionaryDictionary 的键没有任何特定的顺序。我不知道你为什么认为他们会。鉴于有一个 SortedDictionary 类对其键进行排序并且您希望对键进行排序,也许您应该使用它。

标签: vb.net


【解决方案1】:

一个赃物

    Dim chartValues As New SortedDictionary(Of String, Decimal)
    For Each row As DataGridViewRow In DataGridView1.Rows.OfType(Of DataGridViewRow)()
        Dim column14Value As String = row.Cells().Item("Column14").Value.ToString()
        Dim column11Value As Decimal = CDec(row.Cells().Item("Column11").Value)

        If (chartValues.ContainsKey(column14Value)) Then
            chartValues(column14Value) += column11Value
        Else
            chartValues.Add(column14Value, column11Value)
        End If
    Next

    For Each chartValue As Decimal In chartValues.Values
        ComboBox1.Items.Add(chartValue)
    Next

【讨论】:

    【解决方案2】:

    如果你想要一个帕累托图,你想按名称分组,取每组的总和,也取每组的累积总和。您可以在 LINQ 中完成所有这些操作,但我会提醒您不要直接在 DataGridView 中使用数据:您应该让数据远离 UI。但是这个解决方案是根据您的设计使用 LINQ 来完成的。

    Dim sums = DataGridView1.Rows.OfType(Of DataGridViewRow).
        GroupBy(Function(d As DataGridViewRow) d.Cells().Item("Column14").Value.ToString()).
        Select(Function(g) New KeyValuePair(Of String, Decimal)(g.Key, g.Sum(Function(rs) CDec(rs.Cells().Item("Column11").Value)))).
        OrderByDescending(Function(kvp) kvp.Value)
    Dim pareto = sums.Select(Function(kvp, i) New ParetoData(kvp.Key, kvp.Value, sums.Take(i + 1).Select(Function(kvp1) kvp1.Value).Sum()))
    
    ComboBox1.DataSource = pareto.Select(Function(p) $"Name:{p.Key}, Sum:{p.Sum}, Cum:{p.Cumulative}").ToList()
    

    它需要这个类来保存提到的数据。

    Public Class ParetoData
        Public Sub New(key As String, sum As Decimal, cumulative As Decimal)
            Me.Key = key
            Me.Sum = sum
            Me.Cumulative = cumulative
        End Sub
        Public Property Key As String
        Public Property Sum As Decimal
        Public Property Cumulative As Decimal
    End Class
    

    为了在没有你的数据的情况下进行测试,我制作了自己的数据和类来保存它

    Public Class Data
        Public Sub New(column14 As String, column11 As Decimal)
            Me.Column11 = column11
            Me.Column14 = column14
        End Sub
        Public Property Column11 As Decimal
        Public Property Column14 As String
    End Class
    

    在运行上面的解决方案代码之前,我像这样填充了网格

    Dim gridRows As New List(Of Data)()
    gridRows.Add(New data("D", 4))
    gridRows.Add(New data("H", 1))
    gridRows.Add(New data("E", 5))
    gridRows.Add(New data("F", 2))
    gridRows.Add(New data("G", 5))
    gridRows.Add(New data("H", 8))
    gridRows.Add(New data("G", 3))
    gridRows.Add(New data("A", 1))
    gridRows.Add(New data("B", 3))
    gridRows.Add(New data("D", 2))
    gridRows.Add(New data("J", 1))
    gridRows.Add(New data("H", 2))
    gridRows.Add(New data("E", 7))
    gridRows.Add(New data("F", 6))
    gridRows.Add(New data("G", 3))
    gridRows.Add(New data("A", 1))
    gridRows.Add(New data("B", 1))
    gridRows.Add(New data("E", 1))
    gridRows.Add(New data("F", 4))
    gridRows.Add(New data("G", 2))
    gridRows.Add(New data("G", 6))
    gridRows.Add(New data("A", 1))
    gridRows.Add(New data("I", 1))
    gridRows.Add(New data("C", 3))
    gridRows.Add(New data("G", 3))
    gridRows.Add(New data("A", 1))
    gridRows.Add(New data("B", 3))
    gridRows.Add(New data("D", 2))
    gridRows.Add(New data("B", 1))
    gridRows.Add(New data("D", 2))
    gridRows.Add(New data("H", 3))
    gridRows.Add(New data("E", 9))
    
    DataGridView1.DataSource = gridRows
    

    然后把结果放到ComboBox中,是这样的

    【讨论】:

      【解决方案3】:

      最后,我在添加值之前添加了一个排序字典,如下所示:

      Dim chartValues = New SortedDictionary(Of String, Decimal)(StringComparer.Ordinal)
      Dim Total As Decimal
      
      For Each row In DataGridView1.Rows.OfType(Of DataGridViewRow)
          Dim column14Value = row.Cells().Item("Column14").Value.ToString()
          Dim column11Value = row.Cells().Item("Column11").Value
      
          If (chartValues.ContainsKey(column14Value)) Then
              chartValues(column14Value) = chartValues(column14Value) + column11Value
          Else
              chartValues.Add(column14Value, column11Value)
          End If
      Next
      
      Dim sortedDict = (From entry In chartValues Order By entry.Value Descending).ToDictionary(Function(pair) pair.Key, Function(pair) pair.Value)
      
      For Each chartV In chartValues
                  Total += chartV.Value
      Next
      
      For Each chartValue In sortedDict
                  Dim Tot As Decimal
                  Tot += chartValue.Value
                  Chart2.Series(2).Points.AddXY(chartValue.Key, Tot / Total)
                  Chart1.ChartAreas(0).AxisX.Interval = 1
                  Chart2.ChartAreas(0).AxisX.Interval = 1
      Next
      
      

      感谢大家的帮助! :)

      【讨论】:

        猜你喜欢
        • 2022-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-08
        • 2013-05-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多