Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 437
  • Last Modified:

check arraylist for duplicates using IEnumerator

Experts,

I have a address class with properties type_id, address, city, state, country, postal_code. The user can store more than one addresses, and i store the addresses in the session as an arraylist like below and i use vb.net

dim addresses as new arraylist
addresses = session("Addresses")
dim addressinstance as new Address() ' create new instance Class
addressinstance.type_id = 100
addressinstance.address = something.....
.
.
addresses.add(addressinstance)
session("addesses") = addresses

And i need to check if the user has entered the address twice for the same time, and return an error if so. to do this i wrote a function like

Public Shared Function isDuplicate(ByVal input As Int32, ByVal inputArray As ArrayList, ByVal element As String) As ERROR_CODES

        Dim arrayEnumerator As IEnumerator = inputArray.GetEnumerator
        Dim arrayEnumList As ArrayList
        While arrayEnumerator.MoveNext
            If arrayEnumerator.Current.type_ID = input Then
                Return ERROR_CODES.DUPLICATE
            End If
        End While
end function

where input the type_id i need to check, InputArray is the ArrayList , and element has string "TYPE_ID" which the property of Address class.

this works fine. But i need to generalize it to check against any Ararylist which are basically instances of other classes. I have similar for phone etc., i do not want to repeat the code for all. The problem i have is the part that says
If arrayEnumerator.Current.type_ID = input , here instead of type_ID which is only for address class, I need use the element parameter of the function call, since the property i need to check may not neccessarily be "TYPE_ID".
soemthing like  arrayEnumerator.Current.element = input.

Thanks,
0
Sujinig
Asked:
Sujinig
  • 3
  • 2
  • 2
  • +1
1 Solution
 
gregasmCommented:
I don't have time to write an algorithm that does exactly what you ask, but I'd like to refer you to a GREAT PAQ that is similar to what you are trying to achieve.

http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/Q_20943409.html
0
 
SujinigAuthor Commented:
I have modified the my isDuplicate function as

Dim arrayItem As Object
        For Each arrayItem In inputArray
            Dim type As System.Type = arrayItem.GetType
            If type.IsClass Then

                Dim lPropertyInfo As System.Reflection.PropertyInfo = type.GetProperty(element)
                 Dim vString As String = lPropertyInfo.GetValue(Nothing, Nothing).ToString
            End If

        Next

. it bascially checks the gets the type of each array item and if the type is a class then it gets the prorperty info for the element passes as string to the fucntion. And what I am trying is to get the value of the Property. I am getting a TargetException error in the lPropertyInfo.GetValue Line. any ideas on how to get the value of the property.

Exception Details: System.Reflection.TargetException: Non-static method requires a target.

Source Error:


Line 32:                 Dim vString As String = lPropertyInfo.GetValue(Nothing, Nothing).ToString
Line 33:             End If
Line 34:
 

Source File: c:\inetpub\wwwroot\BrandContacts\_Business_Rules\Validation.vb    Line: 32

Stack Trace:


[TargetException: Non-static method requires a target.]
   System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess) +0
   System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean verifyAccess) +422
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +23
   System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index) +38
   BrandContacts.Validation.isDuplicate(Object input, ArrayList inputArray, Object element) in c:\inetpub\wwwroot\BrandContacts\_Business_Rules\Validation.vb:32
   BrandContacts.Contact_Add.SaveAddress(Object sender, EventArgs e) in c:\inetpub\wwwroot\BrandContacts\Contact_Add.aspx.vb:364
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +58
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +18
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
   System.Web.UI.Page.ProcessRequestMain() +1277

 

I did this way so that i can check on any class and it's prpoperties, and also on other arrays that are not classes.

0
 
jackiechen858Commented:
   Public Shared Function isDuplicate(ByVal input As Int32, ByVal inputArray As ArrayList, ByVal element As String) As ERROR_CODES

        Dim arrayEnumerator As IEnumerator = inputArray.GetEnumerator
        While arrayEnumerator.MoveNext
            Dim t As Type
            t = arrayEnumerator.Current.GetType
            Dim f As FieldInfo = t.GetField("element")
           
'should check f as nothing
            If (f.FieldType.Name = "Int32") Then
                Dim nValue As Int32
                nValue = CType(f.GetValue(arrayEnumerator.Current), Int32)
                If nValue = input Then
                    Return ERROR_CODES.DUPLICATE
                End If
            End If
        End While
    End Function
0
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

 
jackiechen858Commented:
sorry, should be
Dim f As FieldInfo = t.GetField(element)

I don't know what's the difference between "Field","Property" or "Member".

what the heck.
0
 
ihenryCommented:
I prefer to do that in OO way. To check for duplicate object use ArrayList.Contains method and also take a look at overriding the Object.Equals method

Object.Equals Method (Object)
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemObjectClassEqualsTopic1.asp

ArrayList.Contains Method
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemCollectionsArrayListClassContainsTopic.asp

And try this quick sample:

Public Class Address

    Public Sub New(ByVal city As String, ByVal postalCode As String)
        m_City = city
        m_PortalCode = postalCode
    End Sub

    Private m_City As String
    Public Property City() As String
        Get
            Return m_City
        End Get
        Set(ByVal Value As String)
            m_City = Value
        End Set
    End Property

    Private m_PortalCode As String
    Public Property PostalCode() As String
        Get
            Return m_PortalCode
        End Get
        Set(ByVal Value As String)
            m_PortalCode = Value
        End Set
    End Property

    Public Overloads Overrides Function Equals(ByVal obj As Object) As Boolean

        Try
            Dim isEqual As Boolean
            'option A: use this if you need to compare the reference object
            'isEqual = MyBase.Equals(obj) And (CType(obj, Address).City = Me.City) And (CType(obj, Address).City = Me.City)
            'option B: use this if the reference object doesn't have to be equal
            isEqual = (CType(obj, Address).City = Me.City) And (CType(obj, Address).City = Me.City)
            Return isEqual
        Catch
            Return False
        End Try

    End Function

    Public Overrides Function GetHashCode() As Integer
        Return m_City.GetHashCode() ^ m_PortalCode.GetHashCode()
    End Function

End Class

'---- usage -------------------------------
        Dim o1 As New Address("city1", "1234")
        Dim o2 As New Address("city2", "2345")

        Dim a As New ArrayList
        a.Add(o1)
        a.Add(o2)

        ' when option A enable:
        Console.WriteLine(a.Contains(o1)) 'true
        Console.WriteLine(a.Contains(o2)) 'true
        Dim o4 As New Address("city1", "1234")
        Console.WriteLine(a.Contains(o4)) 'false

        ' when option B enable:
        Console.WriteLine(a.Contains(o1)) 'true
        Console.WriteLine(a.Contains(o2)) 'true
        Dim o4 As New Address("city1", "1234")
        Console.WriteLine(a.Contains(o4)) 'true


HTH
0
 
ihenryCommented:
Sorry there're some typo errors in my previous post,

    Public Overloads Overrides Function Equals(ByVal obj As Object) As Boolean

        Try
            Dim isEqual As Boolean
            'option A: use this if you need to compare the reference object
            'isEqual = MyBase.Equals(obj) And (CType(obj, Address).City = Me.City) And (CType(obj, Address).PostalCode= Me.PostalCode)
            'option B: use this if the reference object doesn't have to be equal
            isEqual = (CType(obj, Address).City = Me.City) And (CType(obj, Address).PostalCode= Me.PostalCode)
            Return isEqual
        Catch
            Return False
        End Try

    End Function
0
 
jackiechen858Commented:
I think I aslo answered this question.
0
 
SujinigAuthor Commented:
I accept jackiechen858 Solution because it addresses the requirement and works for me. Here is the solution i came up with the Idea derived from jackiechen858

Public Shared Function isDuplicate(ByVal input As Object, ByVal inputArray As ArrayList, ByVal element As Object) As ERROR_CODES
        Dim arrayEnumerator As IEnumerator = inputArray.GetEnumerator
        While arrayEnumerator.MoveNext
            Dim type As System.Type = arrayEnumerator.Current.GetType
            Dim lFieldInfo As System.Reflection.FieldInfo = type.GetField(element)
            If lFieldInfo.FieldType.Name = "Int32" Then
                Dim lValue As Int32 = CType(lFieldInfo.GetValue(arrayEnumerator.Current), Int32)
                If lValue = input Then
                    Return ERROR_CODES.DUPLICATE
                End If
            End If

        End While
End Function
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 3
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now