I have a generic class that will sort a data object on any property that is specified. It sorts by Ascii or a Alphanumerical sort, ascending or decending. Based upon the code here which is also elsewhere.
What I would like to do is simplify the calling of this. I have to use
Data.Sort(New PropertyComparer(Of Plane)("TailNumber",
PropertyComparer(Of Plane).SortDirectionType.Ascending,
PropertyComparer(Of Plane).SortTypeType.AlphaNumeric))
Is there a way to reduce the length of the passed parameters SortDirectionType and SortTypeType?
Sub TestPropertySort()
Dim Data = GetData()
Data.Sort(New PropertyComparer(Of Plane)("TailNumber",
PropertyComparer(Of Plane).SortDirectionType.Ascending,
PropertyComparer(Of Plane).SortTypeType.AlphaNumeric))
print(Data, "Plane sort")
End Sub
Private Function GetData() As List(Of Plane)
Dim Planes As New List(Of Plane)
Planes.Add(New Plane("81192", "Shenyang J-8II"))
Planes.Add(New Plane("30+91", "Eurofighter Typhoon"))
Planes.Add(New Plane("084", "General Dynamics F-16 Fighting Falcon"))
Planes.Add(New Plane("83", "Test3"))
Planes.Add(New Plane("A16-97", "Lockheed Hudson"))
Planes.Add(New Plane("L9162", "Avro Anson"))
Planes.Add(New Plane("CH-06", "Lockheed C-130 Hercules"))
Planes.Add(New Plane("CC-06", "Test 2"))
Planes.Add(New Plane("967", "Test 1"))
Planes.Add(New Plane("966", "CASA C-212 Aviocar 300DF"))
Return Planes
End Function
Public Class PropertyComparer(Of T)
Implements IComparer(Of T)
Public Enum SortDirectionType
Descending = -1
Ascending = 1
End Enum
Public Enum SortTypeType
Ascii
AlphaNumeric
End Enum
Private SortPropertyName As String = ""
Private SortDirection As SortDirectionType
Private SortType As SortTypeType
Public Sub New(ByVal PropertyName As String)
SortPropertyName = PropertyName
SortDirection = SortDirectionType.Ascending
Me.SortType = SortTypeType.Ascii
End Sub
Public Sub New(ByVal PropertyName As String, ByVal Direction As SortDirectionType)
SortPropertyName = PropertyName
SortDirection = Direction
Me.SortType = SortTypeType.Ascii
End Sub
Public Sub New(ByVal PropertyName As String, ByVal Direction As SortDirectionType, ByVal SortType As SortTypeType)
SortPropertyName = PropertyName
SortDirection = Direction
Me.SortType = SortType
End Sub
Public Function Compare(ByVal x As T, ByVal y As T) As Integer Implements System.Collections.Generic.
IComparer(Of T).Compare
'The first thing Compare does is get the PropertyInfo record for the x and y arguments
Dim PropertyX As PropertyInfo = x.GetType().GetProperty(SortPropertyName)
If PropertyX Is Nothing Then Throw New Exception("Sorting on property '" & SortPropertyName & "' bt that property does not exist in the class")
Dim PropertyY As PropertyInfo = y.GetType().GetProperty(SortPropertyName)
If PropertyX Is Nothing Then Throw New Exception("Sorting on property '" & SortPropertyName & "' bt that property does not exist in the class")
'Obtain the value of the property using the argument's x and y and the PropertyInfo record
Dim px As Object = PropertyX.GetValue(x, Nothing)
Dim py As Object = PropertyY.GetValue(y, Nothing)
If SortType = SortTypeType.AlphaNumeric Then
Return CompareAlphaNumeric(Of String)(CType(px, String), CType(py, String)) * SortDirection
Else
'Inspects the type of the property to determine how to call the Compare method implemented at the end of the class.
'The Compare method implemented has a where predicate that limits the types of the parameter K to those that implement IComparable.
'The reason for this Is that IComparable types implement CompareTo.
If (TypeOf px Is Integer) Then Return Compare(Of Integer)(CType(px, Integer), CType(py, Integer)) * SortDirection
If (TypeOf px Is Decimal) Then Return Compare(Of Decimal)(CType(px, Decimal), CType(py, Decimal)) * SortDirection
If (TypeOf px Is Date) Then Return Compare(Of Date)(CType(px, Date), CType(py, Date)) * SortDirection
If (TypeOf px Is Double) Then Return Compare(Of Double)(CType(px, Double), CType(py, Double)) * SortDirection
If (TypeOf px Is String) Then Return Compare(Of String)(CType(px, String), CType(py, String)) * SortDirection
End If
Dim methodX As MethodInfo = PropertyX.GetType().GetMethod("CompareTo")
If (methodX Is Nothing = False) Then
Return CType(methodX.Invoke(px, New Object() {py}), Integer) * SortDirection
Else
Return 0
End If
End Function
Private Function Compare(Of K As IComparable)(ByVal x As K, ByVal y As K) As Integer
Return x.CompareTo(y)
End Function
Public Function CompareAlphaNumeric(Of K As IComparable)(ByVal X As String, ByVal Y As String) As Integer
'Validate the arguments.
If X = Nothing Then Return 0
If Y = Nothing Then Return 0
Dim LengthX As Integer = X.Length
Dim LengthY As Integer = Y.Length
Dim Marker1 As Integer = 0
Dim Marker2 As Integer = 0
'Loop over both Strings.
While Marker1 < LengthX And Marker2 < LengthY
Dim Char1 As Char = X(Marker1)
Dim Char2 As Char = Y(Marker2)
Dim TempX(LengthX) As Char
Dim IndexX As Integer = 0
Dim TempY(LengthY) As Char
Dim IndexY As Integer = 0
'Collect digits for String one.
Do
TempX(IndexX) = Char1
IndexX += 1
Marker1 += 1
If Marker1 < LengthX Then
Char1 = X(Marker1)
Else
Exit Do
End If
Loop While Char.IsDigit(Char1) = Char.IsDigit(TempX(0))
'Collect digits for String two.
Do
TempY(IndexY) = Char2
IndexY += 1
Marker2 += 1
If Marker2 < LengthY Then
Char2 = Y(Marker2)
Else
Exit Do
End If
Loop While Char.IsDigit(Char2) = Char.IsDigit(TempY(0))
'Convert to Strings.
Dim StrX = New String(TempX)
Dim StrY = New String(TempY)
'Parse Strings into Integers.
Dim Result As Integer
If Char.IsDigit(TempX(0)) And Char.IsDigit(TempY(0)) Then
Dim ThisNumericChunk = Integer.Parse(StrX)
Dim ThatNumericChunk = Integer.Parse(StrY)
Result = ThisNumericChunk.CompareTo(ThatNumericChunk)
Else
Result = StrX.CompareTo(StrY)
End If
'Return result if not equal.
If Not Result = 0 Then
Return Result
End If
End While
'Compare lengths.
Return LengthX - LengthY
End Function
End Class
Related
I want to remove all string except string startwith EVOPB-
how can I make it happen ?
Private Sub StringResult()
Try
Dim web As New HtmlDocument()
web.Load(WebBrowser1.DocumentStream)
'' Extracting All Links
Dim redeem As HtmlNode = web.DocumentNode.SelectSingleNode("//div[#class='_58b7']")
If (redeem.InnerText.Contains("")) Then
Dim r As String = redeem.InnerText.ToString.Replace(vbNewLine, "")
TextBox1.Text = r
End If
Catch
Return
End Try
End Sub
Assuming what you are trying to match always starts with the same prefix and runs until the next space, something like this would work:
Public Shared Function ExtractStartsWith(ByVal Output As String, Optional StartsWith As String = "EVOPB") As List(Of String)
Dim pos As Integer = 0
Dim nextSpace As Integer
Dim results As New List(Of String)
Dim result As String
Do While pos >= 0 AndAlso pos < Output.Length
pos = Output.IndexOf(StartsWith, pos)
If pos >= 0 Then
nextSpace = Output.IndexOf(" ", pos)
If nextSpace > 0 Then
result = Output.Substring(pos, nextSpace - pos)
pos = nextSpace + 1
Else
result = Output.Substring(pos)
pos = Output.Length
End If
results.Add(result)
End If
Loop
Return results
End Function
I have a Public class with a Public Shared Dictionary in vb.net. The constructor does not seem to be running. I have a breakpoint in the constructor which does not break. Also when I make a database update, the new values do not show up in the dictionary.
Public Class SkywalkerPolicy
Public Shared CustomPolicies As Dictionary(Of String, String)
Shared Sub New()
CustomPolicies = New Dictionary(Of String, String)
Dim bvin As String = String.Empty
Dim title As String = String.Empty
Dim poldescr As String = String.Empty
Dim dtResult As New DataTable("Result")
dtResult.Locale = System.Globalization.CultureInfo.InvariantCulture
Dim request As New DataRequest
request.Command = "sky_PolicyDictionary_s"
request.CommandType = CommandType.StoredProcedure
request.Transactional = False
Dim result As DataSet
result = SqlDataHelper.ExecuteDataSet(request)
If Not result Is Nothing Then
If result.Tables.Count() > 0 Then
dtResult = result.Tables(0)
For Each row In dtResult.AsEnumerable
bvin = row.Item(1)
title = row.Item(0)
poldescr = row.Item(2)
If CustomPolicies.ContainsKey(title) Then
CustomPolicies(title) += poldescr
Else
CustomPolicies.Add(title, poldescr)
End If
Next
End If
End If
End Sub
End Class
When I access the dictionary, any changes I've made to the data do not show up.
Dim pol As String = SkywalkerPolicy.CustomPolicies("Orders and Shipping Details")
Does anyone have any suggestions as to how I can get the constructor to work?
Or should I have an additional Sub which duplicates initializing the dictionary before I use it?
Thanks
I have a workaround with an Update routine which I call just before accessing the dictionary. But I am still unclear why I can't step through the constructor. So if anyone can answer the original question, I would appreciate an update. Thank you.
Public Class SkywalkerPolicy
Public Shared CustomPolicies As Dictionary(Of String, String)
Shared Sub New()
CustomPolicies = New Dictionary(Of String, String)
Dim bvin As String = String.Empty
Dim title As String = String.Empty
Dim poldescr As String = String.Empty
Dim dtResult As New DataTable("Result")
dtResult.Locale = System.Globalization.CultureInfo.InvariantCulture
Dim request As New DataRequest
request.Command = "sky_PolicyDictionary_s"
request.CommandType = CommandType.StoredProcedure
request.Transactional = False
Dim result As DataSet
result = SqlDataHelper.ExecuteDataSet(request)
If Not result Is Nothing Then
If result.Tables.Count() > 0 Then
dtResult = result.Tables(0)
For Each row In dtResult.AsEnumerable
bvin = row.Item(1)
title = row.Item(0)
poldescr = row.Item(2)
If CustomPolicies.ContainsKey(title) Then
CustomPolicies(title) += poldescr
Else
CustomPolicies.Add(title, poldescr)
End If
Next
End If
End If
End Sub
Public Shared Sub UpdateDictionary()
CustomPolicies.Clear()
Dim bvin As String = String.Empty
Dim title As String = String.Empty
Dim poldescr As String = String.Empty
Dim dtResult As New DataTable("Result")
dtResult.Locale = System.Globalization.CultureInfo.InvariantCulture
Dim request As New DataRequest
request.Command = "sky_PolicyDictionary_s"
request.CommandType = CommandType.StoredProcedure
request.Transactional = False
Dim result As DataSet
result = SqlDataHelper.ExecuteDataSet(request)
If Not result Is Nothing Then
If result.Tables.Count() > 0 Then
dtResult = result.Tables(0)
For Each row In dtResult.AsEnumerable
bvin = row.Item(1)
title = row.Item(0)
poldescr = row.Item(2)
If CustomPolicies.ContainsKey(title) Then
CustomPolicies(title) += poldescr
Else
CustomPolicies.Add(title, poldescr)
End If
Next
End If
End If
End Sub
End Class
Please see the code below:
Private Shared ReadOnly log As ILog = LogManager.GetLogger(GetType(ScheduledTasks))
Private Shared TestString As String = ""
Public Shared Sub writeConsole(ByVal i As Integer)
System.Threading.Thread.Sleep(1000)
TestString = TestString & i
End Sub
Public Shared Sub ParallelTest()
Dim int1 As Integer = 1, int2 As Integer = 2, int3 As Integer = 3, int4 As Integer = 4, int5 As Integer = 5, int6 As Integer = 6, int7 As Integer = 7, int8 As Integer = 8, int9 As Integer = 9, int10 As Integer = 10
Dim list As List(Of Integer) = New List(Of Integer)
list.Add(int1)
list.Add(int2)
list.Add(int3)
list.Add(int4)
list.Add(int5)
list.Add(int6)
list.Add(int7)
list.Add(int8)
list.Add(int9)
list.Add(int10)
Dim ParallelOptions As ParallelOptions = New ParallelOptions
ParallelOptions.MaxDegreeOfParallelism = 1 ' Environment.ProcessorCount * 10
Parallel.ForEach(Of Integer)(list.AsEnumerable(),
Sub(test As Integer)
writeConsole(test)
End Sub)
MsgBox("got here")
When the code reaches the message box, TestString contains the following value: 16237594810. I would expect it to be: 12345678910. It seems to indicate that multiple threads are being used even though MaxDegreeOfParallelism is set to: 1. Why is this?
I tried to create list of object type and get through session the class type list from another page,but it is not working simply coming out of the code when assigment is done.
Public Sub GetvalueContains(ByVal txtFilterText As String, ByVal strColPropertyName As String, ByVal collectionName As String)
Dim FilteredAgentsList As New List(Of Object)
FilteredAgentsList = CType(HttpContext.Current.Session("FilteredAgentsList"), Object)
AgentList = Session("AgentList")
FilteredAgentsList = CType(HttpContext.Current.Session("AgentList"), Object)
Dim FilteredAgentsListdetails As New List(Of Object)
FilteredAgentsListdetails = HttpContext.Current.Session("FilteredAgentsListdetails")
Dim indx As Integer = 0
Dim indexx As Integer = collectionName.IndexOf("_")
indexx = indexx + 1
Dim str As String = collectionName.Substring(indexx, collectionName.Length - indexx)
Dim grdagents As GridView = HttpContext.Current.Session("grdAgents")
If FilteredAgentsListdetails.Count > 0 Then
FilteredAgentsList = FilteredAgentsListdetails
End If
Dim AgentListTemp As List(Of Object) = HttpContext.Current.Session("AgentListTemp")
AgentListTemp = FilteredAgentsList
'FilteredAgentsListdetails = New List(Of Agents)
strColPropertyName = GetPropertyNameAtIndex(AgentListTemp, Convert.ToInt32(hdncellindex.Value))
txtFilterText = txtFilterText.Replace("*", "")
Dim resultList As IEnumerable(Of Object)
resultList = AgentListTemp.Where(Function(x) x.[GetType]().GetProperty(strColPropertyName).GetValue(x, Nothing).ToString().StartsWith(txtFilterText))
'AgentListTemp = CType(resultList.ToList(), List(Of Agents))
'FilteredAgentsListdetails = AgentListTemp
grdagents.DataSource = Nothing
grdagents.DataBind()
grdagents.DataSource = resultList
grdagents.DataBind()
End Sub
how to get the session value in above code?or any other method to pass list from one page to other.
I am little bit confused in this program.
I am new to Visual Basic but intermediate to C.
Actually I want to get sub-string of string without using library function of Visual Basic.
Here is the C source code I also given my VB code too.
1.The Program will get two inputs from user i.e A & B
2. Than Find the substring from B.
3. Finally Print the result.
int i,j=0,k=0,substr=0;
for(i=0;i<strlen(a);i++)
{
if(a[i]==b[j])
{
j++;
if(b[j]==0)
{
printf("second string is substring of first one");
substr=1;
break;
}
}
}
for(i=0;i<strlen(b);i++)
{
if(b[i]==a[k])
{
k++;
if(a[k]==0)
{
printf(" first string is substring of second string");
substr=1;
break ;
}
}
}
if(substr==0)
{
printf("no substring present");
}
While my code is
Dim a As String
Dim b As String
a = InputBox("Enter First String", a)
b = InputBox("Enter 2nd String", b)
Dim i As Integer
Dim j As Integer = 0
Dim k As Integer = 0
Dim substr As Integer = 0
For i = 0 To a.Length - 1
If a(i) = b(j) Then
j += 1
If b(j) = 0 Then
MsgBox("second string is substring of first one")
substr = 1
Exit For
End If
End If
Next i
For i = 0 To b.Length - 1
If b(i) = a(k) Then
k += 1
If a(k) = 0 Then
MsgBox(" first string is substring of second string")
substr = 1
Exit For
End If
End If
Next i
If substr = 0 Then
MsgBox("no substring present")
End If
End Sub
While compiling it gives following debugging errors.
Line Col
Error 1 Operator '=' is not defined for types 'Char' and 'Integer'. 17 24
Error 2 Operator '=' is not defined for types 'Char' and 'Integer'. 27 24
Part of your confusion is that .Net strings are much more than just character buffers. I'm going to assume that you can at least use strings. If you can't, use need to declare character arrays instead. That out of the way, this should get you there as a 1:1 translation:
Private Shared Function search(ByVal a As String, ByVal b As String) As Integer
Dim i As Integer = 0
Dim j As Integer = 0
Dim firstOcc As Integer
While i < a.Length
While a.Chars(i)<>b.Chars(0) AndAlso i < a.Length
i += 1
End While
If i >= a.Length Then Return -1 'search can not continue
firstOcc = i
While a.Chars(i)=b.Chars(j) AndAlso i < a.Length AndAlso j < b.Length
i += 1
j += 1
End While
If j = b.Length Then Return firstOcc
If i = a.Length Then Return -1
i = firstOcc + 1
j = 0
End While
Return 0
End Function
Shared Sub Main() As Integer
Dim a As String
Dim b As String
Dim loc As Integer
Console.Write("Enter the main string :")
a = Console.ReadLine()
Console.Write("Enter the search string :")
b = Console.ReadLine()
loc = search(a, b)
If loc = -1 Then
Console.WriteLine("Not found")
Else
Console.WriteLine("Found at location {0:D}",loc+1)
End If
Console.ReadKey(True)
End Sub
But please don't ever actually use that. All you really need is this:
Private Shared Function search(ByVal haystack as String, ByVal needle As String) As Integer
Return haystack.IndexOf(needle)
End Function
VB has a built-in function called InStr, it's part of the language. It returns an integer specifying the start position of the first occurrence of one string within another.
http://msdn.microsoft.com/en-us/library/8460tsh1(v=VS.80).aspx
Pete
Try this one, this will return a List(Of Integer) containing the index to all occurrence's of the find text within the source text, after the specified search starting position.
Option Strict On
Public Class Form1
''' <summary>
''' Returns an array of indexes where the find text occurred in the source text.
''' </summary>
''' <param name="Source">The text you are searching.</param>
''' <param name="Find">The text you are searching for.</param>
''' <param name="StartIndex"></param>
''' <returns>Returns an array of indexes where the find text occurred in the source text.</returns>
''' <remarks></remarks>
Function FindInString(Source As String, Find As String, StartIndex As Integer) As List(Of Integer)
If StartIndex > Source.Length - Find.Length Then Return New List(Of Integer)
If StartIndex < 0 Then Return New List(Of Integer)
If Find.Length > Source.Length Then Return New List(Of Integer)
Dim Results As New List(Of Integer)
For I = StartIndex To (Source.Length) - Find.Length
Dim TestString As String = String.Empty
For II = I To I + Find.Length - 1
TestString = TestString & Source(II)
Next
If TestString = Find Then Results.Add(I)
Next
Return Results
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
Dim Search As String = "Hello world, this world is an interesting world"
Dim Find As String = "world"
Dim Indexes As List(Of Integer) = New List(Of Integer)
Try
Indexes = FindInString(Search, Find, 0)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
RichTextBox1.Text = "Search:" & vbCrLf
RichTextBox1.Text = RichTextBox1.Text & Search & vbCrLf & vbCrLf
RichTextBox1.Text = RichTextBox1.Text & "Find:" & vbCrLf
RichTextBox1.Text = RichTextBox1.Text & Find & vbCrLf & vbCrLf
RichTextBox1.Text = RichTextBox1.Text & "-----------" & vbCrLf
RichTextBox1.Text = RichTextBox1.Text & "Result Indexes:" & vbCrLf & vbCrLf
For Each i As Integer In Indexes
RichTextBox1.Text = RichTextBox1.Text & i.ToString & vbCr
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
End Class
Here is another way, where there is no use of .Net functions.
Function FindInString(Source As String, Find As String, StartIndex As Integer) As Integer()
If StartIndex > Len(Source) - Len(Find) Then Return {}
If StartIndex < 0 Then Return {}
If Len(Find) > Len(Source) Then Return {}
Dim Results As Integer() = {}, ResultCount As Integer = -1
For I = StartIndex To Len(Source) - Len(Find)
Dim TestString As String = ""
For II = I To I + Len(Find) - 1
TestString = TestString & Source(II)
Next
If TestString = Find Then
ResultCount += 1
ReDim Preserve Results(ResultCount)
Results(ResultCount) = I
End If
Next
Return Results
End Function