Click here to Skip to main content
15,919,613 members
Articles / Programming Languages / C#

Searching in an ArrayList

Rate me:
Please Sign up or sign in to vote.
1.50/5 (9 votes)
12 Aug 2008CPOL1 min read 17.2K   8   9
A smart way to search an ArrayList.

Introduction

I was working on a database oriented application and came to know that I needed a code snippet that can search in an ArrayList. Obviously, if you have stored defined data types directly, it is very easy to search the ArrayList. That is by using the ArrayList.Contains methods. In my case, I had an ArrayList that contained objects of one of my own classes. The .NET Framework doesn't provide such a method to search within custom objects of particular classes. So I worked out a search method that can be used effectively to search within an ArrayList.

Using the Code

You will need to include this method in your code in order to use it.

First of all, we need to create two enums to manage the datatypes and comparisons:

C#
public enum MemberType
{
    IntegerType = 1, StringType = 2, DateTimeType = 3, BooleanType = 4
};

public enum ComparisonOperator
{
    GreaterThan=1,LessThan=2,EqualTo=3
}

Let's create an Employee class. It may be the class you will use and search objects of:

C#
public class Employee
{
    private int e_id;
    private string e_name;
    private DateTime e_dob;
    private bool e_isfemale;

    
    public int EmployeeID
    {
        get { return e_id; }
        set { e_id = value; }
    }

    public string EmployeeName
    {
        get { return e_name; }
        set { e_name = value; }
    }

    public DateTime DateOfBirth
    {
        get { return e_dob; }
        set { e_dob = value; }
    }

    public bool IsFemale
    {
        get { return e_isfemale; }
        set { e_isfemale = value; }
    } 
}

And here is the Search method:

C#
public int Search(ArrayList objArr, string valueToSearch, 
           string FieldName, MemberType memType,ComparisonOperator comOp)
{
    if (memType == MemberType.StringType || memType == MemberType.BooleanType)
    {
        comOp = ComparisonOperator.EqualTo;
    }

    for (int i = 0; i < objArr.Count; i++)
    {
        Type t = objArr[0].GetType();
        System.Reflection.FieldInfo[] arrInner = t.GetFields();
        System.Reflection.PropertyInfo PI = t.GetProperty(FieldName);
        string str  = PI.GetValue(objArr[i], null).ToString();                        
        switch(memType)
        {
            case MemberType.BooleanType:
                if (Convert.ToBoolean(str) == Convert.ToBoolean(valueToSearch))
                {
                    return i;
                }
                break;
            case MemberType.DateTimeType:
                switch (comOp)
                {
                    case ComparisonOperator.EqualTo:
                        if (Convert.ToDateTime(str).CompareTo(
                                Convert.ToDateTime(valueToSearch)) == 0)
                        {
                            return i;
                        }
                        break;
                    case ComparisonOperator.GreaterThan:
                        if (Convert.ToDateTime(str).CompareTo(
                                Convert.ToDateTime(valueToSearch)) > 0)
                        {
                            return i;
                        }
                        break;
                    case ComparisonOperator.LessThan:
                        if (Convert.ToDateTime(str).CompareTo(
                               Convert.ToDateTime(valueToSearch)) < 0)
                        {
                            return i;
                        }
                        break;
                }
                break;
            case MemberType.IntegerType:
                switch (comOp)
                {
                    case ComparisonOperator.EqualTo:
                        if (Convert.ToInt32(str) == Convert.ToInt32(valueToSearch) )
                        {
                            return i;
                        }
                        break;
                    case ComparisonOperator.GreaterThan:
                        if (Convert.ToInt32(str) > Convert.ToInt32(valueToSearch))
                        {
                            return i;
                        }
                        break;
                    case ComparisonOperator.LessThan:
                        if (Convert.ToInt32(str) < Convert.ToInt32(valueToSearch))
                        {
                            return i;
                        }
                        break;
                }
                break;
            case MemberType.StringType:
                if (str.Contains(valueToSearch))
                {
                    return i;
                }
                break;
        }
    }
    return -1;
}

To use the above search function, you will need to do some thing like this:

C#
ArrayList objArr = new ArrayList();
Employee objEmp = new Employee();
objEmp.EmployeeID = 1;
objEmp.EmployeeName = "Usman";
objEmp.IsFemale = false;
objEmp.DateOfBirth = new DateTime(1982,4,1);

objArr.Add(objEmp);

int searchedIndex = Search(objArr, "1", "EmployeeID", 
                    MemberType.IntegerType, ComparisonOperator.EqualTo);
  • objArr: It is the ArrayList in which you are storing your objects.
  • valueToSearch: It is the value which you are trying to search in your list. Remember, you will always pass a string.
  • FieldName: The field you want to search.
  • memType: The DataType of the class member.
  • comOp: The comparison operator that you want to apply on search.

Points of Interest

In this snippet of code, the major part is the System.Reflection namespace usage. This search method can also be extended to support other Data Types.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Marriala Technologies
Pakistan Pakistan
Muhammad Usman
Software Developer, M.sc(Computer)
Pakistan

Comments and Discussions

 
GeneralMy vote of 1 Pin
maxtlab1-Apr-10 4:46
maxtlab1-Apr-10 4:46 
Generalhmmm... Pin
johannesnestler13-Aug-08 23:00
johannesnestler13-Aug-08 23:00 
GeneralRe: hmmm... [modified] Pin
evolved14-Aug-08 3:47
evolved14-Aug-08 3:47 
If the data types stored in the collection not homogeneous but you need to perform an operation on them, then you can still use anonymous delegates, but it's a bit different. Of course, there are a number of ways to do this, I'll explain a couple here. But first I would like to point out that if you encounter this situation, it has a code smell - it's not immediately terrible, but it's an odd requirement and you should consider looking back over at your implementation.

1, anonymous delegates, object data type >

List<object> things = new List<object>();

// fill things with employees and monkeys (what are you implying here Johan  :rolleyes:)

things.Find(delegate(object o) { 
   if(o is Employee) { return (o as Employee).EmployeeID = 13; }
   if(o is Monkey) { return (o as Monkey).MonkeyID = 13; }
   return false;
});


2, implement a common interface on both Employee and Monkey - IRidiculed

public interface IRidiculed { int ID { get; } string Name { get; } float Salary { get; } }

// implement the above interface on both employee and monkey classes...

List<IRidiculed> things = new List<IRidiculed>();

// fill things with both monkeys and employees

things.Find(delegate(IRidiculed item){
   return item.ID == 13;
});

Reflection is a last resort. Very powerful, very useful, but in this situation, an area that computer science has tackled over and over (abstract data type / data structure searching), theres no need to reinvent the wheel here.

A reimplementation of your code sans reflection could use the first method above, ie:

items.Find(delegate(object o) { return (o is Monkey) && (o as Monkey).MonkeyID == 13 });


Alternatively, a few methods like this:

public IEnumerable<Monkey> GetMonkeys(ArrayList list) {
    foreach(object o in list)
         if(o is Monkey) yield return (o as Monkey);
}
public IEnumerable<Employee> GetEmployees(ArrayList list) {
    foreach(object o in list)
         if(o is Employee) yield return (o as Employee);
}


and then you can do specifics on just the types you are interested in:

ie: non-homogeneous array list example -

ArrayList foo = new ArrayList();

// fill with monkeys, employees

foreach(Employee e in GetEmployees(foo)) {
  // do something to employees
}


modified on Thursday, August 14, 2008 10:29 AM

GeneralRe: hmmm... Pin
johannesnestler14-Aug-08 22:47
johannesnestler14-Aug-08 22:47 
GeneralRe: hmmm... Pin
M Usman14-Aug-08 20:59
M Usman14-Aug-08 20:59 
GeneralRe: hmmm... Pin
evolved18-Aug-08 3:51
evolved18-Aug-08 3:51 
GeneralRe: hmmm... Pin
M Usman18-Aug-08 21:56
M Usman18-Aug-08 21:56 
GeneralThe framework does indeed provide such functionality. [modified] Pin
evolved13-Aug-08 8:17
evolved13-Aug-08 8:17 
GeneralRe: The framework does indeed provide such functionality. Pin
M Usman14-Aug-08 20:53
M Usman14-Aug-08 20:53 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.