473,224 Members | 1,685 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,224 software developers and data experts.

Generic List object

We have several generic List objects in our project. Some of them
have about 1000 items in them. Everytime we have to find something,
we have to do a for loop. There is one method which does the
searching, but that method receives the object, and the string to
search in that object and runs the FOR loop to find the answer.

This is taking time because we have to do searching hundres of times.

I want to use Hashtable, but the problem is that I will have to change
158 files. Any suggestion as to what I can do to make my life not so
miserable?

It would be perfect, if I could just make this method faster (for loop
would have to be removed?), or if I could just convert the type from
List to Hashtable in this method and then quickly find it.

Any ideas?

Thanks

Feb 13 '07 #1
7 16640
There is one method which does the
searching, but that method receives the object, and the string to
search in that object and runs the FOR loop to find the answer.

... just convert the type from
List to Hashtable in this method and then quickly find it.
First: for replacing List<T>, you want to use Dictionary<string, T>,
not Hashtable (using string keys as mentioned). With this done, you
would simply have to update this method to use the dictionary methods
(indexer if you strongly believe the item is in the Dictionary;
TryGetValue if you can't be sure).

However! Changing to Dictionary will change a few things; for
instance, it won't be IEnumerable<Tany more (IIRC it is
IEnumerable<KeyValuePair<TKey,TValue>>, with separate .Keys
and .Values properties). Secondly, the sequence becomes undefined
(Dictionary does not respect insertion order).

Perhaps what you need is something that behaves like a Collection<T>
(since List<Tnot very easy to inherit), but handles an inner
Dictionary? To allow for Add(T), this would mean that the key would
have to be obtainable from the item... hmm...

How about below; is still IEnumerable<T>, etc, but you just need to
update your entities to support the Key, and your search method to use
the indexer (in your case, since no conflict between String and
Int32); if you can't add the Key, then you'd presumably need to change
the Add methods, or use some form of key-provider similar to the hash-
code provider (aka IEqualityComparer<T>).

Marc

using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
static class Program
{
static void Main()
{
IndexedList<string, MyDataitems = new IndexedList<string,
MyData>();
items.Add(new MyData("Item 1"));
items.Add(new MyData("Item 2"));
items.Add(new MyData("Item 3"));

MyData item = items["Item 2"];
}
}

public class MyData : IKeyed<string>
{
// lazy fields instead of properties...
public MyData(string @ref)
{
Ref = @ref;
}
public readonly string Ref; // key should be immutable for
hashtable
public string Name;
public string AddressLine1;
public int Something;

string IKeyed<string>.Key { get { return Ref; } }
}

public interface IKeyed<T{
T Key {get;}
}
public class IndexedList<TKey, TValue: Collection<TValuewhere
TValue : IKeyed<TKey>
{
public TValue this[TKey key] {
get { return _index[key]; }
}
// "get by" for when TKey is int, which causes indexer conflict
public TValue GetByKey(TKey key)
{
return _index[key];
}
public TValue GetByIndex(int index)
{
return base[index];
}
public bool TryGetByKey(TKey key, out TValue value)
{
return _index.TryGetValue(key, out value);
}
public IndexedList(IEqualityComparer<TKeykeyComparer)
{
_keyComparer = keyComparer ?? EqualityComparer<TKey>.Default;
}
public IndexedList() : this(null) { }

private readonly IEqualityComparer<TKey_keyComparer;
private readonly Dictionary<TKey, TValue_index = new
Dictionary<TKey, TValue>();
protected override void InsertItem(int index, TValue item)
{
_index.Add(item.Key, item); // checks unique before adding to
either list
base.InsertItem(index, item);
}

protected override void RemoveItem(int index)
{
_index.Remove(this[index].Key);
base.RemoveItem(index);
}
protected override void ClearItems()
{
_index.Clear();
base.ClearItems();
}
protected override void SetItem(int index, TValue item)
{
TKey oldKey = this[index].Key, newKey = item.Key;
if (_keyComparer.Equals(oldKey, newKey))
{ // key same; update existing
_index[newKey] = item;
}
else if (_index.ContainsKey(newKey))
{ // key changed but now a duplicate
throw new ArgumentException("Duplicate key");
}
else
{ // key changed; remove and re-add
_index.Remove(oldKey);
_index.Add(newKey, item);
}
base.SetItem(index, item);
}
}
Feb 13 '07 #2
IF you want a nice named object, then

public class PersonCollection : System.Collections.Generic.List
<Person>

{

}

Below is something cool I found

I found it at:

http://www.google.com/search?hl=en&q...IteratorAction

Matt Berther

using System;

using System.Collections.Generic;

using System.Text;

namespace HowToDoCollections

{

public delegate void IteratorActionDelegate(object sender , Person per);

public class PersonCollection : System.Collections.Generic.List <Person>

{

public void Iterate(object sender , IteratorActionDelegate action)

{

foreach (Person p in this)

{

action(sender, p);

}

}

}

}

namespace HowToDoCollections

{

public class Person

{

#region Member Variables

private string _firstName = string.Empty;

private string _lastName = string.Empty;

private string _uid = System.Guid.NewGuid().ToString("N");

#endregion

#region Constructors

public Person()

{

}

public Person(string firstName, string lastName)

{

this.FirstName = firstName;

this.LastName = lastName;

}

#endregion

#region Properties

public string FirstName

{

get { return _firstName; }

set { _firstName = value; }

}

public string LastName

{

get { return _lastName; }

set { _lastName = value; }

}

public string UID

{

get { return _uid; } //ReadOnly

}

#endregion

}

}



class Program

{

private static PersonCollection
personCollectionWithLargerThanMethodScope = new PersonCollection();

private static void SayHello(object sender , Person per)

{

Console.WriteLine("Hello, {0} {1}", per.FirstName,
per.LastName);

}

private static void TellUserIWasNotVerified(object sender, Person
per)

{

Console.WriteLine("NOT VERIFIED : {0} {1}", per.UID,
per.LastName + " " + per.FirstName);

}

private static void VerifyAllPersons(object sender, Person per)

{

if (per.FirstName.Length <= 0 || per.LastName.Length <= 0)

{

//you need something that lives outside of the method to
track them

personCollectionWithLargerThanMethodScope.Add(per) ;

}

}

static void Main(string[] args)

{

try

{

PersonCollection p1 = new PersonCollection();

p1.Add(new Person("John", "Smith"));

p1.Add(new Person("Cindy", "Brady"));

p1.Add(new Person("", "Madonna"));

p1.Add(new Person("Mary", "Jones"));

p1.Add(new Person("Cher", ""));

p1.Iterate(System.Environment.UserName , new
IteratorActionDelegate(SayHello));

Console.WriteLine("\n\r\n\r");

p1.Iterate(System.Environment.UserName, new
IteratorActionDelegate(VerifyAllPersons));

personCollectionWithLargerThanMethodScope.Iterate( null, new
IteratorActionDelegate(TellUserIWasNotVerified));

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

finally

{

Console.WriteLine("\n\r\n\rPress ENTER to end.");

Console.Read();

}



}

}
Feb 13 '07 #3
Ammendments:

1: remove _keyComparer (not necessary)

2: in the ctor, initialise the Dictionary as follows: _index = new
Dictionary<TKey, TValue>(keyComparer);

3: replace references to _keyComparer with _index.Comparer

Note that (as per other poster) you can use the Find method on
List<T>, but this still enumerates internally, so O(n); the Dictionary
approach is closer to O(1).

Marc

Feb 13 '07 #4
frick!!! I meant:

_index = new Dictionary<TKey, TValue>(keyComparer ??
EqualityComparer<TKey>.Default);

Feb 13 '07 #5
On Feb 13, 4:05 pm, "Sehboo" <MasoodAd...@gmail.comwrote:
We have several generic List objects in our project. Some of them
have about 1000 items in them. Everytime we have to find something,
we have to do a for loop. There is one method which does the
searching, but that method receives the object, and the string to
search in that object and runs the FOR loop to find the answer.

This is taking time because we have to do searching hundres of times.

I want to use Hashtable, but the problem is that I will have to change
158 files. Any suggestion as to what I can do to make my life not so
miserable?

It would be perfect, if I could just make this method faster (for loop
would have to be removed?), or if I could just convert the type from
List to Hashtable in this method and then quickly find it.

Any ideas?

Thanks
Hi,

Why not use the generic Dictionary collection instead? It use a
hashtable implementation as well.

Do the contents of the List collections change or are they pretty
static? If they are static then you could sort the list once and use
the BinarySearch method.

Also, did you know there was no need to code your own loop for
searching? List already has the Find method.

Brian

Feb 13 '07 #6
if you have 1,000 of anything; put it in a database

C# does not scale well enough to store 1,000 items in memory


On Feb 13, 2:05 pm, "Sehboo" <MasoodAd...@gmail.comwrote:
We have several generic List objects in our project. Some of them
have about 1000 items in them. Everytime we have to find something,
we have to do a for loop. There is one method which does the
searching, but that method receives the object, and the string to
search in that object and runs the FOR loop to find the answer.

This is taking time because we have to do searching hundres of times.

I want to use Hashtable, but the problem is that I will have to change
158 files. Any suggestion as to what I can do to make my life not so
miserable?

It would be perfect, if I could just make this method faster (for loop
would have to be removed?), or if I could just convert the type from
List to Hashtable in this method and then quickly find it.

Any ideas?

Thanks

Feb 14 '07 #7
Good to see our local troll has a new face

Feb 15 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: majm | last post by:
I'm trying to implement strongly typed lists in the 2.0 framework. I'm using VS2005 beta 2. So far, System.Collections.Generic.List appears to be the ideal solution. However, the...
0
by: crazyone | last post by:
I've got a gaming framework i'm building and i want to save myself the trouble of reading and writting the complete game data to a custom file and load/save it to an XML file but i'm getting...
4
by: rsa_net_newbie | last post by:
Hi there, I have a Managed C++ object (in a DLL) which has a method that is defined like ... Generic::List<String^>^ buildList(String^ inParm) Now, when I compile it, I get "warning C4172:...
1
by: Deckarep | last post by:
Dear CSharp Group, Both of these techniques work as expected but what is the better way of doing this? Or does it even make a difference? Method 1: public delegate void MyDelegate(string...
3
by: Doug | last post by:
I have a generic list object with a property called, "MarkedForDeletion". During the course of my processing, some of the objects in the list will get this property set to true and so at the end...
7
by: =?Utf-8?B?Sm9lbCBNZXJr?= | last post by:
I have created a custom class with both value type members and reference type members. I then have another custom class which inherits from a generic list of my first class. This custom listneeds...
4
by: tadmill | last post by:
Hi, Is it possible for a generic list class to use Reflection on the generic type being used to detect a property within that type that refers to the same generic class, only with a different...
3
by: Taurin | last post by:
I have a method that I would like to be able to pass a generic list (such as List<string>, List<int>, etc). I'm trying to figure out what would be the best type of parameter to use to pass in the...
6
by: phancey | last post by:
I want to define a class like this class MyClass { List<TMyList<Twhere T : IMyList {get; set;} } or something like this. I don't want to put <Ton my class definition
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.