So I have the gui set up so that I have two main listboxes. I'm still figuring out what kind of gui I want for this application so there is another one but that's not relevant. One listbox is a list of options for what you want to check for a department or an employee. The other is a list of departments. Right now I have the functionality for the name option to view the names of employees for a department. I just need to know how I can filter a list so that the only employees that show up are the ones who are in the chosen department after I click on the submit button. I figured I would use a lambda expression for that and it hasn't been working for me. I really want to know how to use lambda expressions better so please only give me a solution that involves using them. If it's impossible or if it would be more efficient to do something else then let me know.
File where I put reads and set dept array to file contents
//list of employees
public static List<Employee> EmployeeList = new List<Employee>();
//array to hold the options users have for interacting with info
public static string[] OptionsArr;
//array to hold the departments
public static string[] DeptsArr;
//skipping around same file to relevant code
//set the departments array to the contents of the depts file
DeptsArr = File.ReadAllLines("..\\..\\departments.txt");
Not sure if needed Method for populating DeptListBox
private void UpdateDeptListBox()
{
//set up for new info
DeptListBox.Items.Clear();
//prevent interfence with update
DeptListBox.BeginUpdate();
//set department listbox to depts array
DeptListBox.DataSource = Program.DeptsArr;
DeptListBox.EndUpdate();
}
Problem Method - the submit button method
List<Employee> ResultList = new List<Employee>();
//name
if (OptionsListBox.SelectedIndex == 1)
{
//user selects Marketing department
if (DeptListBox.SelectedIndex == 0)
{
//problem is either with lambda exp or Program.DeptsArr comparison
foreach (Employee empl in Program.EmployeeList.Where(empl => empl.Dept.CompareTo(Program.DeptsArr[0]) == 0).ToList())
{
//this doesn't happen
ResultList.Add(empl);
}
for (int i = 0; i<ResultList.Count; i )
{
ResultListBox.Items.Add(ResultList[i].Lname " " ResultList[i].Fname " " ResultList[i].Dept);
}
}
}
}
CodePudding user response:
If you want to test whether a specific value is in an array then you call Contains
on that array, e.g.
var allEmployees = new List<Employee>();
// Populate allEmployees here.
var selectedEmployees = allEmployees.Where(e => selectedDepartments.Contains(e.Department)).ToArray();
The selectedEmployees
array will contain only the Employee
objects from the allEmployees
list with a Department
property value that is contained in the selectedDepartments
array/collection.
CodePudding user response:
For me it can be helpful when I am having issues to break stuff down and look at smaller pieces. Are you sure the issue is your lambda function? It may be your options listbox != 1 or that the data is not being read in correctly.
As far as I can tell, this part should work. Although there are some issues with it:
foreach (Employee empl in Program.EmployeeList.Where(empl =>empl.Dept.CompareTo(Program.DeptsArr[0]) == 0).ToList())
{
//this doesn't happen
ResultList.Add(empl);
}
You could start with just the Employee lambda function and hard code the values. Maybe something like this which does indeed produce the correct results (Bob and Brandon)
List<Employee> ResultList = new List<Employee>();
List<Employee> EmployeeList = new List<Employee> {
new Employee{ Name = "Bob", Dept = "Accounting" },
new Employee{ Name = "Larry", Dept = "A" },
new Employee{ Name = "Margret", Dept = "B" },
new Employee{ Name = "Brandon", Dept = "Accounting" }
};
string[] DeptsArr = new string[2];
DeptsArr[0] = "Accounting";
DeptsArr[1] = "A";
//user selects Marketing department
if (departmentIndex == 0)
{
foreach (Employee empl in EmployeeList.Where(empl => empl.Dept.CompareTo(DeptsArr[0]) == 0).ToList())
{
ResultList.Add(empl);
}
}
However your lamda function inside a foreach loop is redundant. You can think of a lambda function as an instruction for running a foreach loop. A foreach loop by itself could look like this:
List<Employee> ResultList = new List<Employee>();
foreach (Employee empl in EmployeeList)
{
if(empl.Dept == DeptsArr[0])
{
ResultList.Add(empl);
}
}
You could get the same result as the foreach loop above, by using the following lamda function:
List<Employee> ResultList = EmployeeList.Where(empl => empl.Dept == DeptsArr[0]).ToList();
A final note is that the "ToList()" on the end of that lambda function is what executes the loop and returns the result as a List. Many times this is not required. Without the "ToList()" part an IEnumerable will be returned which you may be able to use instead. Using an IEnumerable instead of calling ToList() can have better performance in many scenarios.