Reputation: 11
I'm writing a program that needs to perform a search as one of the required functions. The user should be able to use any number of fields, ranging from none to all of them (total of 7). So far I've had success grouping each case of data input within an if statement like so:
List<TypeClass> myList = new List<TypeClass>
foreach TypeClass currentItem in myList
{
if (data1 == currentItem.GetData1() || data1 == "Do Not Search" && (data2 == currentItem.GetData2() || data2 == "Do Not Search") && (data3...)
{
//Stuff
}
}
If you notice, I grouped each data field within brackets, so the statement can only be satisfied if each of the entered data is either the needed condition, or an 'empty field'. However, I can't group the very first portion of the statement as I do with the other data2,3,4... Instead the statement always gets evaluated to true even if there are other search fields that do not satisfy the conditions of the statement. If I use additional brackets the program completely ignores the if statement and treats it as if none of the cases match at all.
So if I write it like this:
if ((data1 == currentIten.GetData1 || data1 == "Do Not Search") && (data2...)
Nothing gets checked and the statement is ignored. Is this normal? Are there any better/more efficient ways of dealing with optional search field selection?
EDIT: Sorry for the typo, each GetDataX is an accessor and I forgot to write the parentheses ()
Upvotes: 0
Views: 22589
Reputation: 29264
I would move the matching inside the class and instead of dealing with 7 separate possible values to match, make them one class instance called criteria
. See sample code below:
public enum States
{
None,
Tenesee,
Georgia,
Colorado,
Florida
}
class Item
{
public States State { get; set; }
public string Name { get; set; }
public int ID { get; set; }
public bool IsMatch(Item criteria)
{
bool match = true;
if (criteria.State != States.None) match &= criteria.State == State;
if (!string.IsNullOrEmpty(criteria.Name)) match &= criteria.Name.Equals(Name);
if (criteria.ID > 0) match &= criteria.ID == ID;
return match;
}
public override string ToString()
{
return string.Format("ID={0}, Name={1}, State={2}", ID.ToString(), Name, State.ToString());
}
}
class Program
{
static void Main(string[] args)
{
List<Item> list = new List<Item>();
list.Add(new Item() { ID = 10016, Name = "Julia", State = States.Georgia });
list.Add(new Item() { ID = 10017, Name = "Scott", State = States.Colorado });
list.Add(new Item() { ID = 10018, Name = "Samantha", State = States.Tenesee });
list.Add(new Item() { ID = 10019, Name = "Julia", State = States.Florida });
Item criteria = new Item()
{
State = States.Tenesee,
ID = 10018
};
List<Item> selection = list.FindAll((item) => item.IsMatch(criteria));
foreach (var item in selection)
{
Console.WriteLine("{0}", item);
}
}
}
With the result
ID=10018, Name=Samantha, State=Tenesee
So you build a criteria instance Item
and compare for a match if a property is well defined. The loop through all the items and select the ones that match the criteria. Obviously you have to extend .IsMatch()
for all 7 properties.
Upvotes: 0
Reputation: 7334
Put all the possibilities in hashset .
Hashset with all possibilities.
foreach(item in selectedItems) //you may not need this if you dont have to perform action forall selected items.
{
if (Hashset contains item)
//do stuff.
}
Upvotes: 0
Reputation: 2771
You could do it like this for an or condition
List<string> mylist = new List<string>();
string data1 = "test1";
string data2 = "test2";
string data3 = "test3";
string data4 = "test4";
foreach (string s in mylist)
{
bool found = false;
if(data1.Equals(s) || data1.Equals("Do not Search"))
{
found = true;
}
if (data2.Equals(s) || data1.Equals("Do not Search"))
{
found = true;
}
if (data3.Equals(s) || data1.Equals("Do not Search"))
{
found = true;
}
if (data4.Equals(s) || data1.Equals("Do not Search"))
{
found = true;
}
}
Or like this for an and condition
List<string> mylist = new List<string>();
string data1 = "test1";
string data2 = "test2";
string data3 = "test3";
string data4 = "test4";
foreach (string s in mylist)
{
bool found = false;
bool notfound = false;
if(data1.Equals(s) || data1.Equals("Do not Search"))
{
found = true;
}
else
{
notfound = true;
}
if (data2.Equals(s) || data1.Equals("Do not Search"))
{
found = true;
}
else
{
notfound = true;
}
if (data3.Equals(s) || data1.Equals("Do not Search"))
{
found = true;
}
else
{
notfound = true;
}
if (data4.Equals(s) || data1.Equals("Do not Search"))
{
found = true;
}
else
{
notfound = true;
}
// Force all to match
if (notfound)
return null;
}
My Preference would be something like this though where you can leverage search functions to do what you need to.....
List<string> mylist = new List<string>();
List<string> mysearches = new List<string>();
string data1 = "test1";
string data2 = "test2";
string data3 = "test3";
string data4 = "test4";
if(data1 != "Do not Search")
mysearches.Add(data1);
if (data2 != "Do not Search")
mysearches.Add(data2);
if (data3 != "Do not Search")
mysearches.Add(data3);
if (data4 != "Do not Search")
mysearches.Add(data4);
bool found = false;
bool andconditionmatch = true;
foreach (string s in mylist)
{
if (mysearches.Contains(s))
{
found = true;
}
else
{
andconditionmatch = false;
}
}
Upvotes: 2