loop through string and calculate column subtotals vb net 2010 - asp.net

i have a string with 1 value per line. i call it ttl_count.
ttl_count looks like this
1
1
1
0
0
0
1
1
1
1
0
etc
1's and 0's
What i want to do is run down the column of numbers in 'ttl_count' and total the consecutive groupings of 1. using the example above:
1
1
1 >> 3
0
0
0
1
1
1
1 >> 4
0
Here we see 2 consecutive groups, one with a subtotal of 3, and the other 4. i want to send each calculated subtotal into another variable to determine the MAX value and if the last entry in the variable is '1' to show the current subtotal.
not quite sure how to do this.

You can use the String.Split and String.Join Methods. Since you mentioned that you had one value per line I am assuming that you are reading from a file and have the standard windows CRLF endings. The first Split removes the line ending, I then join it back together so you have a string of just ones and zeros. I then split on the zeros which will give you an array with just ones in it. At that point it would just be as simple as using the String.Length Method on each Array element to get the Total number of ones in each string. If you are wanting to write the information back into the source(I am assuming a file) will require you to iterate through the string and count the ones then append the subtotal to the existing string and write that back to a file.
Module Module1
Sub Main()
Dim splitFirst As String() = {vbCrLf}
Dim splitNext As String() = {"0"}
Dim testString As String = "1" & vbCrLf &
"1" & vbCrLf &
"1" & vbCrLf &
"0" & vbCrLf &
"0" & vbCrLf &
"0" & vbCrLf &
"1" & vbCrLf &
"1" & vbCrLf &
"1" & vbCrLf &
"1" & vbCrLf &
"0"
Dim results As String() = testString.Split(splitFirst, StringSplitOptions.RemoveEmptyEntries)
Dim holding As String = String.Join("", results)
results = holding.Split(splitNext, StringSplitOptions.RemoveEmptyEntries)
'Show the results
For Each item In results
Console.WriteLine(item & " Count = " & item.Length.ToString())
Next
Console.ReadLine()
End Sub
End Module
Here is the same idea as a Function returning a String Array with the Groups of 1's as individual items.
Public Function getColumnCounts(data As String) As String()
Dim splitFirst As String() = {vbCrLf} 'Seperator used to strip CrLf's
Dim splitNext As String() = {"0"} 'Seperator used to strip the 0's
'This is where the CrLf information is removed
Dim results As String() = data.Split(splitFirst, StringSplitOptions.RemoveEmptyEntries)
'Join the results array to make a string
Dim holding As String = String.Join("", results)
'Split it again to remove the blocks of zero's leaving just groups on ones in the array
results = holding.Split(splitNext, StringSplitOptions.RemoveEmptyEntries)
'Return the results as a String Array
'For Example
'For Each item In getColumnCounts(testString)
' Console.WriteLine(item & " Count = " & item.Length.ToString())
'Next
Return results
End Function

Related

Include match index in Regex replacement string

I have a situation where I need to strip out HTML code from some text. However, some of the input text includes lists, and I want to retain the numbering in that case.
If I do
result = Regex.Replace(result, "<li>", vbNewLine & "1. ", RegexOptions.IgnoreCase)
Then after stripping out the other HTML tags, I end up with:
1. List item one
1. List item two
1. List item three
Is there a way to get the index of the match during replacement?
so for example:
result = Regex.Replace(result, "<li>", vbNewLine & replacementIndex + 1 & " ", RegexOptions.IgnoreCase)
Then after stripping out the other HTML tags, I would get:
1. List item one
2. List item two
3. List item three
Is this possible??
Note: This is inside a function, so that each list is handled separately, and unordered lists get bullets (*) instead.
This should be a good starting point. #"(\<ul\>)((.|\n)*?)(\<\/ul\>)" this will match everything in between the tags.
It's messy, but something like the following. Only change one at a time. This may be slow for large data sets.
int lineNbr = 1;
string newResult = result.Replace("(?i)<li>", vbNewLine & (lineNbr++).ToString() & '. ', 1);
while (newResult != result)
{
result = newResult;
newResult = result.Replace("(?i)<li>", vbNewLine & (lineNbr++).ToString() & '. ', 1);
}
Here's how I ended up doing it - first, find each ordered list:
Dim result As String = rawText
Dim orderedLists As MatchCollection = Regex.Matches(rawText, "<ol>.*?</ol>", RegexOptions.Singleline)
For Each ol As Match In orderedLists
result = Replace(result, ol.Value, EncodeOrderedList(ol.Value))
Next
And the function to convert each one:
Private Function EncodeOrderedList(ByVal rawText As String) As String
Dim result As String = rawText
result = Regex.Replace(result, "<ol>\s*<li>", "1. ", RegexOptions.IgnoreCase)
result = Regex.Replace(result, "</li>\s*</ol>", vbNewLine & vbNewLine, RegexOptions.IgnoreCase)
Dim bullets As MatchCollection = Regex.Matches(rawText, "</li>\s*<li>")
Dim i As Integer = 2
For Each li As Match In bullets
result = Replace(result, li.Value, vbNewLine & i & ". ", 1, 1)
i += 1
Next
Return result
End Function
I haven't tested it on nested lists.

How to show keys in a Motobit Multi.Dictionary by the given item value?

I'm new to programming so I'm sorry if my question seems dumb. I want to ask if there is any way to return the keys from Multi.Dictionary when I have the value?
This is my code:
Dim myDict
Set myDict= Server.CreateObject("Multi.Dictionary")
myDict.UniqueKeys = False
'Fill dictionary with some data
myDict("param1") = "value1"
myDict.Add "param2", "value2"
myDict.Add "param2", "value2.2"
'Get dictionary Keys
Keys = myDict.Keys
Items = myDict.Items
For Z = 0 To UBound(Items)
Response.Write(Keys(Z) & " " & Items(Z) & "<br>")
Next
And for now returns
Subscript out of range: '2'
Which is normal because I loop 3 times while I have only 2 keys.
So is it possible to have a result like this:
Param1: "value1"
Param2: "value2"
Param2: "value2.2"
You can loop through the keys of myDict by checking the items multiple or not.
Dim myDict
Set myDict= Server.CreateObject("Multi.Dictionary")
myDict.UniqueKeys = False
myDict("param1") = "value1"
myDict.Add "param2", "value2"
myDict.Add "param2", "value2.2"
Dim key, subItem
For Each key In myDict.Keys
If IsArray(myDict(key)) Then ' item is an array
For Each subItem In myDict(key)
Response.Write key & ": " & subItem & "<br>"
Next
Else
Response.Write key & ": " & myDict(key) & "<br>"
End If
Next

Dynamically Adding data to jagged array?

I have a recursive function that creates a list of items based on their hierarchy(integer is used to determine which level 1 to 10 max). There can be x number of items in any given level. I want to store all the items that belong the same level at the corresponding index of the jagged array. The items aren't retrieved based on their level so the level can be jumping around all of over the place as the function recurses.
Function RecurseParts(lngPartID1, lngLevel) As Object
'this function will recursivley print the parts lists for the part ID passed in
If IsNumeric(lngPartID1 & "") Then
Dim objRSTemp As Object = Server.CreateObject("ADODB.Recordset")
objRSTemp.CursorLocation = adUseClient
objRSTemp.Open(PART_LIST_SQL & lngPartID1, objConn, adOpenForwardOnly, adLockReadOnly)
'objRSTemp.ActiveConnection = Nothing
If objRSTemp.eof And objRSTemp.bof Then
'PROBLEM, WE HAVE NO RECORDS
Response.Write("There Were No Parts For This Assembly (Part ID #:" & lngPartID1 & ")")
Else
'make output
Dim strTemp As String = String.Empty
If lngLevel <> 1 Then strTemp = " style=""display: none;"">"
Response.Write("<table id='tblparts" & lngCurrentLineNum & "' border=""0"" cellspacing=""0"" width=""100%"" cellpadding=""1"" " & strTemp)
Do Until objRSTemp.EOF
'increase the current line num
lngCurrentLineNum = lngCurrentLineNum + 1
'get current Part ID
lngCurrentPartID = objRSTemp("PartID").value
'reset flag
blnIsAssm = False
'loop thru array of assemblies to see if this is a parent
For ctr = 0 To UBound(arrAssmList, 2)
If arrAssmList(0, ctr) = lngCurrentPartID Then
'the current part is an assembly
blnIsAssm = True
Exit For
ElseIf arrAssmList(0, ctr) > lngCurrentPartID Then
Exit For
End If
Next
If blnIsAssm Then
'recurse these parts
If RecurseParts(objRSTemp("PartID").value, lngLevel + 1) = True Then
'awesome
End If
End If
objRSTemp.MoveNext()
Loop
Response.Write("</table>")
End If
If objRSTemp.State Then objRSTemp.Close()
objRSTemp = Nothing
'RETURN FUNCTION
RecurseParts = True
Else
'no PART ID passed in
Response.Write("No Part ID Passed In")
RecurseParts = False
End If
End Function
It sounds like a Dictionary would work here.
Dim myDict As New Dictionary(Of Integer, List(Of String))
In your recursive function. The parts in the {} are the parts you have to supply.
'this builds the keys as you go
If Not myDict.ContainsKey({{key} -> your Integer}) Then
'add key and use the From statement to add a value if know at this time
myDict.Add({key}, New List(Of String) From {value})
Else
myDict({key}).Add({string to insert at this level})
End If
List of keys in reverse order:
Dim keys = myDict.Keys.OrderByDescending(Function(k) k)
I was able to create a List to store all the partIDs and their levels.
Dim arrSubID As New List(Of List(Of Integer))()
Function RecurseParts(paramenters)
For ctr = 0 To UBound(arrAssmList, 2)
If arrAssmList(0, ctr) = lngCurrentPartID Then
'checks whether we need a new index in the list
If lngLevel + 1 > arrSubID.Count Then
arrSubID.Add(New List(Of Integer))
End If
'adds the partID where it belongs!
arrSubID(lngLevel).Add(lngCurrentPartID)
blnIsAssm = True
Exit For
ElseIf arrAssmList(0, ctr) > lngCurrentPartID Then
Exit For
End If
Next
End Function

How to reuse an array in asp.net vb

I'm having to build a table of web pages and languages, i.e. page 1: en it de in a schema where there could be up to 14 languages. The page contents are held in a database. So to build the table I'm doing the following:
Dim rowArrayList As New ArrayList
Dim thisRow(languageNum) As String 'languageNum equates to number of columns -1
Database access then:
'# Create row array of cell arrays
If pageName <> lastPageName Then
lastPageName = pageName
If j >= languageNum Then
rowArrayList.Add(thisRow)
Array.Clear(thisRow, 0, thisRow.Length)
j = 0
End If
thisRow(0) = "<td class=""pageName"">" & pageName & "</td>"
End If
'# Iterate each cell in the row
For i As Integer = 1 To languageNum - 1
If thisRow(i) = "" Then
If transReady = False And active = False Then
thisRow(i) = "<td class=""trans"">" & langISO & "</td>"
ElseIf transReady = True And active = False Then
thisRow(i) = "<td class=""notActive"">" & langISO & "</td>"
ElseIf transReady = True And active = True And i = thisLangID Then
thisRow(i) = "<td class=""active"">" & langISO & "</td>"
End If
End If
j = j + 1
Next
The build the table:
'# Build output table
For Each row As String() In rowArrayList
tableBody.Text += "<tr>"
For Each cell As String In row
If cell = "" Then
tableBody.Text += "<td class=""notTrans""> </td>"
Else
tableBody.Text += cell
End If
Next
tableBody.Text += "</tr>"
Next
The table displays beautifully BUT every row contains the data for what should be the last row. How can it be fixed it so each thisRow is unique in the the rowArrayList? At the moment, every time thisRow is added to rowArrayList, every rowArrayList index is overwritten, not just the one being added.
For the quick fix, instead of this:
Array.Clear(thisRow, 0, thisRow.Length)
Do this:
thisRow = New String(languageNum) {}
or this:
ReDim thisRow(languageNum)
However, I suspect there are some simple design choices you could change that would drastically change this code for the better.

ASP Classic - How to count the number of sub items in a nested list

I have a nested list that I use to display available videos from the db grouped under their respective headers.
I'm wondering if it's possible to count the number of videos in each grouping so that I could display it like this:
Video Group Title 1 (3 videos)
1. Video 1
2. Video 2
3. Video 3
Video Group Title 2 (6 videos)
1. Video 1
2. Video 2
...etc.
The SQL is pretty simple right now:
SELECT * FROM video_module_type;
I'm using ASP VBscript and the code for what I've got is:
<%
'----------------------------------------------------------------------------------------------------
'VARIABLES
'----------------------------------------------------------------------------------------------------
Dim previous_video_module_name
Dim first_video_module_name
Dim DIV_vms_vid_title
Dim DIV_vms_grouping
Dim DIV_video_section_group
Dim DIV_vms_video_holder
Dim DIV_vms_sm_thumb
Dim DIV_vms_results
Dim vms_shim
Dim DIV_end
previous_video_module_name = ""
first_video_module_name = true
DIV_vms_vid_title = "<div class=""vms_vid_title"">"
DIV_vms_grouping = "<div id=""sustvid_webinar"" class=""vms_grouping"">"
DIV_video_section_group = "<div class=""video_section_group"">"
DIV_vms_video_holder = "<div class=""vms_video_holder"">"
DIV_vms_sm_thumb = "<div class=""vms_sm_thumb"">"
DIV_vms_vid_synopsis = "<div class=""vms_vid_synopsis"">"
DIV_vms_results = "<div class=""vms_results"">"
vms_shim = "<img src=""/images/shim.gif"" width=""16"" height=""16"">"
DIV_end = "</div>"
'----------------------------------------------------------------------------------------------------
'IF NOT THE SAME VALUE AS PREVIOUS
'----------------------------------------------------------------------------------------------------
for i = 0 to videoModulesListerNumber-1
if video_module_name(i) <> previous_video_module_name then
'------------------------------------------------------------------------------------------
'IF NOT THE FIRST TIME, CLOSE THE NESTED LIST
'------------------------------------------------------------------------------------------
if first_video_module_name then
response.Write("<h2>" & video_module_name(i) & "</h2>")
end if
'------------------------------------------------------------------------------------------
'DISPLAY THE CATEGORY
'------------------------------------------------------------------------------------------
response.Write("<!--START VIDEO GROUP: " & video_module_name(i) & "-->")
'------------------------------------------------------------------------------------------
'IF NOT THE SAME VALUE AS PREVIOUS OPEN THE NESTED LIST AND STORE THE CURRENT
'VALUE FOR COMPARISON NEXT TIME
'------------------------------------------------------------------------------------------
previous_video_module_name = video_module_name(i)
end if
'------------------------------------------------------------------------------------------
'DISPLAY THE VIDEOS
'------------------------------------------------------------------------------------------
response.Write(DIV_vms_grouping)
response.Write(DIV_video_section_group)
response.Write(DIV_vms_video_holder)
response.Write(DIV_vms_vid_title & "<h2>" & video_module_video_name(i) & "</h2>" & DIV_end)
response.Write(DIV_vms_sm_thumb & video_module_thumbnail(i) & DIV_end)
response.Write(DIV_vms_vid_synopsis)
response.Write("<p>" & video_module_synopsis(i) & "</p>")
response.Write(DIV_vms_results & vms_shim & DIV_end)
response.Write(DIV_end) ' close DIV_vms_grouping
response.Write(DIV_end) ' close DIV_video_section_group
response.Write(DIV_end) ' close DIV_vms_video_holder
'------------------------------------------------------------------------------------------
'IT'S NO LONGER THE FIRST TIME; CHANGE THE "first_video_module_name" VARIABLE
'------------------------------------------------------------------------------------------
first_video_module_name = false
next
%>
I think the problem may be that I don't know what the term for this is, so I can't search for it, but any help would be appreciated.
You can change your query to something like
SELECT video_module_type.*, (SELECT COUNT(*)
FROM video_module_type as t2
WHERE t2.Group = video_module_type.VideoGroup) as GroupCount
FROM video_module_type
And use the GroupCount field.
OR
You can traverse the results two times, the first time counting the items and the second time displaying the results
OR
You can use Javascript to count the items and display the results
->JsFiddle Example

Resources