By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,905 Members | 1,628 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,905 IT Pros & Developers. It's quick & easy.

Generic List object

P: n/a
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
Share this Question
Share on Google+
7 Replies


P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
frick!!! I meant:

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

Feb 13 '07 #5

P: n/a
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

P: n/a
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

P: n/a
Good to see our local troll has a new face

Feb 15 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.