Solved

check arraylist for duplicates using IEnumerator

Posted on 2004-09-08
9
415 Views
Last Modified: 2012-06-21
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
Comment
Question by:Sujinig
  • 3
  • 2
  • 2
  • +1
9 Comments
 
LVL 8

Expert Comment

by:gregasm
ID: 12009656
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
 

Author Comment

by:Sujinig
ID: 12010664
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
 
LVL 7

Expert Comment

by:jackiechen858
ID: 12011189
   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
 
LVL 7

Accepted Solution

by:
jackiechen858 earned 250 total points
ID: 12011229
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
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 20

Expert Comment

by:ihenry
ID: 12013459
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
 
LVL 20

Expert Comment

by:ihenry
ID: 12013824
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
 
LVL 7

Expert Comment

by:jackiechen858
ID: 12247667
I think I aslo answered this question.
0
 

Author Comment

by:Sujinig
ID: 12247863
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

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now