Get SUM of Unique Value in a collection - vb.net

I'm looking to get the SUM of unique values in an excel worksheet using VB.net.
I am using a collection
So far my code gets me the Distinct Values, however I'm stumped on the Count side of things.
I feel like I'm close, but something is missing...
My data could look like:
Apple
Apple
Peach
Cherry
I'm looking for Results to be:
Apple 2
Peach 1
Cherry 1
This is where I am:
MySub:
Dim c, r As Range
Dim i As Integer
Dim dc As New Collection
Dim s As String
For Each c In r
dc.Add(c.Value, c.Value)
Next c
For i = 1 To dc.Count
s = dc.Item(i)
Next i
This produces my distinct list of values, but I'm not seeing how to obtain the SUM of those values.
Thanks for any pointers.

Assuming this really is VB.Net, you could use a Dictionary(Of String, Integer) like this:
Dim counts As New Dictionary(Of String, Integer)
For Each c In r
If Not counts.ContainsKey(c.Value) Then
counts.Add(c.Value, 0)
End If
counts.Item(c.Value) = counts.Item(c.Value) + 1
Next c
For Each pair In counts
Debug.Print(pair.Key & " " & pair.Value)
Next

Related

Dim n variables where n is a user defined number

I have to dim n variables in my software, where n is a number that user types in the interface. I'd start with a for loop, in order to declare these variables, with something like:
for i = 0 to n
dim r.i as IRow = worksheet.CreateRow(i)
next
This is what I think but obviously I know that's wrong. Does anyone knows if this is possible? I can't create neither List(Of) nor arrays because these are rows of an excel file I'm trying to export, otherwise NPOI returns me error.
What does Excel have anything to do with not using a List? You can absolutely use worksheet.CreateRow() with a list:
Dim rows As New List(Of IRow)
For i As Integer = 0 to n - 1
rows.Add(worksheet.CreateRow(i))
Next
Now the name of each row is row(0), row(1), row(2) ... row(n - 1)
If you've tried this and NPOI is giving you an error, you should show that code around where the error is thrown and tell us what the error is.
Based on comments:
'Assuming everything has the same number of entries as ListBox1, per the comments
Dim rows As New List(Of IRow)
Dim row As IRow = worksheet.CreateRow(0)
row.CreateCell(0).SetCellValue("Time")
row.CreateCell(1).SetCellValue("hrr")
For i As Integer = 0 To ListBox1.Items.Count - 1
row = worksheet.CreateRow(i+1)
row.CreateCell(0).SetCellValue(ListBox1.Items(i))
row.CreateCell(1).SetCellValue(ListBox2.Items(i))
rows.Add(row)
Next i

read datable and store value in array

Name | CategorieID | FullCategorie_ID
---- ------------- ----------------
A 1 12
B 1 13
C 5 14
D 3 15
E 6 16
I want to read data from datatable and store a complete row in array and then return it
I cannot get the point to save a DataTable (that has rows and columns) inside an Array (that has only rows) but this is your question, not mine!
So, the code you are looking for is something like this:
Dim dt As New System.Data.DataTable
Dim arrayString(dt.Rows.Count - 1) As String
For dr As Integer = 0 To dt.Rows.Count
For dc As Integer = 0 To dt.Columns.Count
arrayString(dr) = arrayString(dr) & "$" & dt.Rows(dr).Item(dc)
'I added a special char ($) to easily split up data later
Next
Next
If you want to split up in columns your data, just use String.Split like shown below:
Dim first_array_row () as String = arrayString.Split("$")
But I higly suggest you to review your code/idea, It's better for you to find another way, because this workaround is horrible.
Instead why not use a List Class and a Dictionary Class
something like:
Dim values As New List(Of Dictionary(Of String, String))()

How to find frequency of each element in DatagridView

I have a DataGridView which looks a little like this:
ColumnName
hello
hello
bye
hello
bye
crocodile
hello
crocodile
How do I find the count of each element? i.e Hello = 4, bye = 3 and crocodile = 2
Seeing as they're outputted in a DataGridView column.
Please help
There is probably a better way to query the DataGridView but looping and creating groups with Linq also works. So this is my idea to do it:
Sub CountRows()
Dim lstCountRows as List(Of String)
For Each row As DataGridViewRow In MyDataGridView.Rows
'2 is the index of the column you are querying
lstCountRows.Add(row.Cells(2).Value)
Next
'Create groups for the values on lstCountRows
Dim groups = lstCountRows.GroupBy(Function(value) value)
'Loop and print the groups count
For Each group In groups
MsgBox(group(0) & "-" & group.Count)
Next
End Sub
Give it a try and let me know your comments

VB LINQ - Take one random row from each group

I'm trying to get one random row from each group of rows. I'm trying to use LINQ, but I'm not sure if that's the right approach. I'd like a Dictionary of Key/Name pairs.
My table is as such:
AnswerGroup AnswerKey AnswerName
---------------------------------------------
1 1 Yes
1 2 No
2 1 Never
2 2 A little bit
2 3 Mostly
2 4 Always
3 1 White
3 2 African American
3 3 Hispanic
3 4 Asian or Pacific Islander
For each AnswerGroup I need to choose a random Key/Name pair.
I have the beginnings of a LINQ query, but frankly I'm lost as I don't understand LINQ grouping and how to add an Enumerable.Take(1) to the group.
Dim answerGroup As String = "AnswerGroup"
Dim answerKey As String = "AnswerKey"
Dim answerName As String = "AnswerName"
Dim query = _
From rows As DataRow In surveyAnswerKeys.Rows _
Order By rows(answerGroup) _
Group By questionSortKey = rows(answerGroup) _
Into questionGroups = Group
Any help would be appreciated. Thanks!
Edit:
I can expand the following query in the debugger to see an In Memory Query that produces a series of DataRows. When I hover over questionGroups it says it's a IEnumerable(Of Object). When I try to run that query into a list or DataTable I get error:
"Public member 'ToTable' on type 'WhereSelectEnumerableIterator(Of
VB$AnonymousType_0(Of Object,IEnumerable(Of Object)),Object)' not
found."
Dim answerGroup As String = "QuestionSortKey"
Dim answerNo As String = "AnswerNo"
Dim surveyDefinitionNo As String = "Pk_SurveyDefinitionNo"
Dim query = _
From rows In surveyAnswerKeys.Rows _
Where rows(answerNo) IsNot Nothing _
Order By Guid.NewGuid() _
Group By questionSortKey = rows(answerGroup) _
Into questionGroups = Group _
Select questionGroups.First()
Dim randomAnswerNos As DataTable = query.ToTable
One quick way to shuffle items is to sort by a "random" value - Guid.NewGuid() usually works well enough. Then just pull the first row from each group:
Dim query = _
From rows As DataRow In surveyAnswerKeys.Rows _
Order By Guid.NewGuid() _
Group By questionSortKey = rows(answerGroup) _
Into questionGroups = Group _
Select questionGroups.First()
Linq can't be used to pull a random row. I'd suggest you store all of the rows in a table and manually loop through each group. Then based on the number of rows in each group, generate a random number and pick that row. Only use LINQ to do the query and retrieve the results.

How to count string occurences in a list(Of String)

I am looking to dynamically count from a list, how many times items have occured. I can do it below if I specify the value I am looking for, but what I am really looking to do is to iterate through my list, count occurences, and total them out. My current code is below:
Dim itemlist As New List(Of String)
itemlist.add("VALUE1")
itemlist.add("VALUE2")
itemlist.add("VALUE3")
Dim count As Integer = 0
For Each value In itemlist
If value.Equals("VALUE1") Then count += 1
Next
Msgbox(count.tostring)
So my point would be instead of searching for the value, let the app total them up and display the counted occurences it to the user, similar to a "COUNTIF" in excel. I cant find much on this without using LINQ, Thanks
You can do this very easily with LINQ:
Msgbox(itemlist.Where(Function(value) value = "VALUE1").Count)
To count duplicates, once again it's easy with LINQ:
Dim itemlist As New List(Of String)
itemlist.Add("RED")
itemlist.Add("RED")
itemlist.Add("RED")
itemlist.Add("GREEN")
dim groups = itemList.GroupBy(Function(value) value)
For Each grp In groups
Console.WriteLine(grp(0) & " - " & grp.Count )
Next
Output:
RED - 3
GREEN - 1