开发者

search arraylist by property using binarysearch

I currently have an arraylist containing classes in C#. The arraylist is filled like this:

 foreach (XmlElement Path 开发者_如何学运维in locaties)
                    {


                        ISoundSource track = engine.AddSoundSourceFromFile(Path.InnerXml);

                        mixarray.Add(track);

                    }

then the array has many ISoundSource classes as its items. Now the thing that sets them apart in the array is their 'name' property. Later on I want to get the ISoundSource from the array by doing a search. I looked up on how to search arraylists and it is said to use a binarysearch but I don't see a way to look up an object with a certain property. How can I get the item from the array which has the name I specify?


You should probably use a Dictionary<,> as it will be much easier to maintain. Also, you should use List<> instead of ArrayList. If you must use BinarySearch, you will have to pass it a custom implementation of IComparer in order to have it use the Name property. Here's an example with a dictionary:

var dictionary = new Dictionary<string, ISoundSource>();
foreach (XmlElement Path in locaties)
{
    ISoundSource track = engine.AddSoundSourceFromFile(Path.InnerXml);
    mixarray.Add(track);
    dictionary[track.Name] = track;
}

ISoundSource item = dictionary["MyTrackName"];


Check out the two parameter overload of BinarySearch which takes an IComparer as the second parameter - you then need to create a small class that inherits from IComparer that will compare the names of two of your Track objects, and pass an instance of this comparer into the BinarySearch.


There are many ways to do what you're asking for, and the right way depends on information that you haven't provided:

  • Does the Name property uniquely identify items?
  • Does every item have a Name?
  • Does the match have to be exact?
  • Is it important to know what order the items were originally added to the list in, i.e. the order that they appear in the source XML?
  • Are you trying to find items given their Name, or access them in order by their Name?
  • How important is it that this be efficient?

It may be that the right solution is to simply use LINQ to find an item:

ISoundSource track = mixarray
   .Cast<ISoundSource>
   .Where(x => x.Name == name)
   .FirstOrDefault();

which will set track to the first item in the list whose name matches the value you're looking for, and to null if there's no match found. (If you use a List<ISoundSource> instead of an ArrayList, you can omit the Cast<ISoundSource> - one of many, many reasons to use List<T> over ArrayList in most cases.)

Most of the time I'll use a Dictionary<TKey, TValue> for this kind of thing, but that's because most the time the answers to those questions are yes, yes, yes, no, don't care about the order, pretty important.


For posterity, here is an alternative way to generate a dictionary using a simple Linq expression.

var dictionary = locaties
    .Select(p->engine.AddSoundSourceFromFile(Path.InnerXml))  
    .ToDictionary(t->t.Name);

The .Select() transforms each node into an ISoundSource. When done, a collection (IEnumerable of ISoundSource) is returned. The .ToDictionary() then converts that list of ISoundSource to a Dictionary of string, ISoundSource.

This requires .NET Framework 3.5 or higher.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜