Finding an object property in list

G

Guest

Hello,

I am trying to avoid using a DataTable to find particular data rows, because
I believe generic.list(of someobject) is faster. Unfortunately, two
seperately instantiated objects do not have the same hashcode so I am unable
to compare them within a Contains() call [even though they contain the same
data]. I know this is what primary keys are for but I wanted to know if
there is a way to use Contains() on a list object, such as:

Public Class SentenceContent
Public Sentence As String
Public Score As Integer
Public Sub New(ByVal Sentence As String, ByVal Score As Integer)
Me.Sentence = Sentence
Me.Score = Score
End Sub
End Class
Public Sentences As New Generic.List(Of SentenceContent)

Sentences.Add(New SentenceContent("testing", 1))
Sentences.Add(New SentenceContent("testing 1", 2))
Sentences.Add(New SentenceContent("testing 2", 3))
Sentences.Add(New SentenceContent("testing 3", 4))
Sentences.Add(New SentenceContent("testing 4", 5))
Sentences.Add(New SentenceContent("testing 5", 6))
Sentences.Add(New SentenceContent("testing 6", 7))
If Sentences.Contains(New SentenceContent("testing 5", 6)) Then
test.Text = "Contains" & "<br/>"
Else
test.Text = "NOT Contains" & "<br/>"
End If

I'm sure this is old news to you but I would very much appreciate your input
here.

Thanks!

mpaine
 
M

Moty Michaely

Hello,

I am trying to avoid using a DataTable to find particular data rows, because
I believe generic.list(of someobject) is faster. Unfortunately, two
seperately instantiated objects do not have the same hashcode so I am unable
to compare them within a Contains() call [even though they contain the same
data]. I know this is what primary keys are for but I wanted to know if
there is a way to use Contains() on a list object, such as:

Public Class SentenceContent
Public Sentence As String
Public Score As Integer
Public Sub New(ByVal Sentence As String, ByVal Score As Integer)
Me.Sentence = Sentence
Me.Score = Score
End Sub
End Class
Public Sentences As New Generic.List(Of SentenceContent)

Sentences.Add(New SentenceContent("testing", 1))
Sentences.Add(New SentenceContent("testing 1", 2))
Sentences.Add(New SentenceContent("testing 2", 3))
Sentences.Add(New SentenceContent("testing 3", 4))
Sentences.Add(New SentenceContent("testing 4", 5))
Sentences.Add(New SentenceContent("testing 5", 6))
Sentences.Add(New SentenceContent("testing 6", 7))
If Sentences.Contains(New SentenceContent("testing 5", 6)) Then
test.Text = "Contains" & "<br/>"
Else
test.Text = "NOT Contains" & "<br/>"
End If

I'm sure this is old news to you but I would very much appreciate your input
here.

Thanks!

mpaine

Dear mpaine,

Yes, you can do that by the Find method of the generic list, and a
specific predicate.

The Find method searches for an element that matches the conditions
defined by the specified predicate.
The Predicate is a delegate to a method that returns true if the
object passed to it matches the conditions defined in the delegate.The
elements of the current List are individually passed to the Predicate
delegate, moving forward in the List, starting with the first element
and ending with the last element. Processing is stopped when a match
is found.

Since the search is linear it's an O(n) operation where n is the
number of elements in the list.

If you need faster search capabilities, try using other data
structures (such as Hashtable (O(1)) - to solve the hashcode problem,
just derive from the class that would be the key and make sure to
return the same hashcode for objects that are equal, or Dictionary
(O(1)) with specified comparer).

Hope this helps,
Moty.
 
L

Linda Liu [MSFT]

Hi Mpaine,

List(Of T) doesn't support the function you want. The reason is as what you
have said--different object instances have different hash code.

Dictionary(Of TKey, TValue) should meet your requirement.

I thought a possible workaround is to derive a new type from List<T> and
override the Contains method. Unfortunately, the Contains method isn't
overridable. So it seems it is impossible to get the List(Of T) to support
the function you want.

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
M

Moty Michaely

Hi Mpaine,

List(Of T) doesn't support the function you want. The reason is as what you
have said--different object instances have different hash code.

Dictionary(Of TKey, TValue) should meet your requirement.

I thought a possible workaround is to derive a new type from List<T> and
override the Contains method. Unfortunately, the Contains method isn't
overridable. So it seems it is impossible to get the List(Of T) to support
the function you want.

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer tohttp://msdn.microsoft.com/subscriptions/managednewsgroups/default.asp...
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) athttp://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Dear Linda,

The List(of T) does contain a method that determines whether the List
contains elements that match specified conditions.
Methods like Exists or Find can suite for the OP needs.

All he has to do is implement a delegate (anonymous delegate would be
great for this purpose) to be used as a predicate (equality comparer).

Contains method is the same as exists. It just determines equality
using the default equality comparer EqualityComparer.Default for T,
the type of values in the list.

To match his needs he just have to call exists with his type of
equality comparer.

Moty
 
G

Guest

just as a friendly followup, I found the easiest solution for my needs -- use
structures instead of classes, they automatically compare the internal data
for equals on their hashcodes.
 
L

Linda Liu [MSFT]

Hi Mpaine,

Thank you for sharing your solution with us.

Structure is a value type. When two value type objects are compared, the
values contained in the two objects are compared actually.

But note that a struct is considered a lightweight class, ideal for
creating data types that store small amounts of data, and does not
represent a type that might later be extended via inheritance.

BTW, I'd like to thank Moty for pointing out the Exists and Find method of
the List(Of T) class. I think it is a good solution to this problem.

If you have any other question in the future, please don't hesitate to
contact us. It's always our pleasure to be of assistance!

Thank you for using our MSDN Managed Newsgroup Support Service!

Sincerely,
Linda Liu
Microsoft Online Community Support
 
M

Moty Michaely

Hi Mpaine,

Thank you for sharing your solution with us.

Structure is a value type. When two value type objects are compared, the
values contained in the two objects are compared actually.

But note that a struct is considered a lightweight class, ideal for
creating data types that store small amounts of data, and does not
represent a type that might later be extended via inheritance.

BTW, I'd like to thank Moty for pointing out the Exists and Find method of
the List(Of T) class. I think it is a good solution to this problem.

If you have any other question in the future, please don't hesitate to
contact us. It's always our pleasure to be of assistance!

Thank you for using our MSDN Managed Newsgroup Support Service!

Sincerely,
Linda Liu
Microsoft Online Community Support

Hi,

Linda is right about structures. It should not be used if it's
intended to extension in the future.

I would override the IComparable interface for equality purposes.

Linda - Glad I could point that out.

Have a great day,
Moty
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top