Click here to Skip to main content
Click here to Skip to main content

SearchList: a quick sorted list, implemented using .NET Generics

By , 19 Jun 2005
 

Introduction

I am writing an editor for Torque Script files, and I wanted to add Intellisense to it. The problem is that I have this huge list of functions and properties available to script and I need to sort and list them as fast as possible. A full scan was inevitable as I wanted to show every item that started with the characters entered by the user. A very good friend (Hello Daniel!) suggested this approach, and here is the implementation of this fast sorted list. In this article, I haven't implemented the search list as a class, but you could do it easily. My goal was to find a solution to the problem and as it ended up very nice, I decided to share it.

SearchList Implementation

The idea is quite simple with the use of .NET Generics: Have an index list that will group your keys for fast access, as it will reduce the final amount of keys to search. The search list is declared like this:

SortedList <string, SortedList<string, string>> alphabet;

The alphabet variable is our index list. It will keep the first character of all keys added to the internal lists, hence its name. The value of alphabet is another list, our "real" list, that will contain the keys and values we want to store. So, let's say we have these function names:

InitDedicatedClient
OnCycleExec
OnExit
OnGameDurationEnd

Using the AddToList() method, we add these values. Two keys will be created in alphabet: "i" and "o". Here is the method listing:

private function AddToList(string key, string value)
{
    // get index (first character)
    string idx = GetAlphaIndex(key);
 
    // find sub-list
    SortedList<string, string> list = null;
 
    if (!alphabet.TryGetValue(idx, out list))
    {
        // new index
        list = new SortedList<string, string>();    
 
        alphabet.Add(idx, list);
    }
 
    try
    {
        list.Add(key, value);
    }
    catch
    {
        System.Diagnostics.Debug.Write("Key [" + key + "] already exists!");
    }
}

The alphabet["i"] value is a SortedList containing one key: InitDedicatedClient. alphabet["o"] will have a SortedList with three keys: OnCycleExec, OnExit and OnGameDurationEnd.

Searching for values

In my project, I need to do a full scan and filter the words that start with the characters typed in the editor. This is done inside this function:

private void RefreshList()
{
    listBox1.Visible = false;
    listBox1.Items.Clear();
    string start = textBox1.Text;

    // add items to listbox
    if (start.Length == 0)
    {
        // add all items, no filter
        foreach (SortedList<string, string> list in alphabet.Values)
        {
            string[] keys = new String[list.Count];
            list.Keys.CopyTo(keys, 0);
            listBox1.Items.AddRange(keys);
        }
    }
    else
    {
        // get from alphabet the SortedList that contains our keys
        string idx = GetAlphaIndex(start);
        SortedList<string, string> list = null;

        if (alphabet.TryGetValue(idx, out list))
        {
            string[] keys = new String[list.Count];
            list.Keys.CopyTo(keys, 0);

            //do a fullscan looking for matches
            foreach (string s in keys)
            {
                bool bCanStop = false;
                StringComparison sct = StringComparison.OrdinalIgnoreCase;
                if (bCaseSensitive)
                    sct = StringComparison.Ordinal;

                if (s.StartsWith(start, sct))
                {
                    // found item that match;
                    // from now on, stop loop after first mismatch
                    bCanStop = true;
                    listBox1.Items.Add(s);
                }
                else
                {
                    // mismatch: Can stop searching for matches?
                    if (bCanStop)
                        break;
                }
            }
        }
    }
    listBox1.Visible = true;
}

Thank you!

Please feel free to add any comments. If you are going to use this code, please mail me and add a reference to this article in your application credits. Thanks for reading and... That's all folks!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Luciano Bargmann
Web Developer
France France
Member
Interested in C#, ASP.NET and games programming;

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralVery Good...memberMasudur18 Feb '08 - 21:51 
At least i know one technique to maintain list while providing auto complete or intelisense
 

GeneralExcellent Demomemberganesan balachandar20 Dec '06 - 4:24 
I used your sample to build an intellisense support for a database that has 45000 (table names and column names). I used your searchlist sample to shortlist this 45000 keywords depending on what was entered by the user.
 
Now, in the article you have mentioned that you are building an editor. Can you provide the sourcecode of that, that would help me to make the editor better.
 

Thanks and Regards
Balachandar Ganesan.

 
I want to fully utilize every thing.

GeneralRe: Excellent DemomemberLuciano Bargmann20 Dec '06 - 7:04 
The editor project got burried under other more important projects, and I really don't know in what state I left this project on.
 
Currently, for Torque Script, I'm (slowly) trying to use VSIP and add a new language support in my Visual Studio.
 
I will search for the project on my backups and I will let you know. Maybe I can wipe out the dust and we could work on it toghether Wink | ;)
 
Btw, I empirically know that this works fine, but I haven't used it with that amount of data before. How is the performance when using 45000 items?
 
HunterKiller

GeneralRe: Excellent Demomemberganesan balachandar20 Dec '06 - 7:07 
Good to hear.
Thanks for the interest and quick response.
We can work on it together and I am definitely willing to proceed from what ever stage you have left the editor.
 
About performance with 45000+ keywords, .................. IT ROCKS!!!!
 
Great Work!!!

 
I want to fully utilize every thing.

GeneralVery usefull functionmemberRoberto 'Obi-Wan' Colnaghi Junior23 Oct '06 - 9:58 
We're always in need of better search algorithms. Big Grin | :-D
QuestionForget something?memberfwsouthern19 Jun '05 - 18:27 
How about source/project files?
AnswerRe: Forget something?memberLuciano Bargmann21 Jun '05 - 7:14 
Fixed.
Blush | :O
 
HunterKiller
GeneralRe: Forget something?membertbenami16 Aug '06 - 23:37 
I've downloaded the source code, but still no sources available.
FYI - the demo application seems very cool
AnswerRe: Forget something?memberLuciano Bargmann17 Aug '06 - 9:37 
I re-downloaded the code and its all there... In the zip root you will find SearchList.sln and SearchList folder; inside SearchList folder you have the project files, and a bin folder containing the executable you may have run.
 
Although this algorithm did his job on fastening things up on my project, I realise that when writing such a public article I should have given some numbers to allow comparison on how fast (or not) this can get. I just forgive myself cause this was my first article ever. Smile | :)
 
I think I will revisit the code and add the performance numbers to the this article.
 
BTW, I can send you the project files if you want.
 
HunterKiller

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 19 Jun 2005
Article Copyright 2005 by Luciano Bargmann
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid