Get maximum Count Lists Nested inside a list - c#

I have a list of employees, and all of them have another list nested which is called the DisplayList.
Now not all the employees have the same amount of DisplayFields. So I wish to get those with the highest DisplayFields, so that I can incorporate everyone in the display.
At the moment I have the following :-
int iMaxDisplayCount = 0;
foreach (Employee employee in employeeList)
{
int iDisplayCount = employee.EmployeeDisplayCollection.Count;
if (iDisplayCount > iMaxDisplayCount)
iMaxDisplayCount = iDisplayCount;
}
var employees = employeeList.GroupBy(p => p.EmployeeDisplayCollection.Count == iMaxDisplayCount).Select(g => g.ToList());
foreach(var employeeHighList in employees)
{
foreach (var employee in employeeHighList)
{
}
}
however for some reason, I am getting all the employees in the employeeHighList and not just the ones who have the highest display count.
I think the GroupBy is not correct, but don't know what's wrong with it.
Any help will be very much appreciated!
Thanks

var max = employeeList.Max(e=>e.EmployeeDisplayCollection.Count);
var maxEmp = employeeList.Where(e=>e.EmployeeDisplayCollection.Count == max)
.ToList()

Related

Getting a list of objects of 2 different lists

I have a list of action type objects. Each object has a list of departments.
I have a user and a user object has n number of deparments.
I would like to get a list of user actions that the user can take. Here is what I came up with:
List<Item> userActions = new List<Item>();
foreach (var actionType in actionTypelist)
{
foreach (var dept in actionType.availableDepts)
{
if (data.currentUser.secondaryServDepts.Where(x => x.Id == dept.servDeptId).Count() > 0)
{
userActions.Add(actionType);
}
}
}
Can you please suggest a better way to get a quicker result? Thanks in advance.
One possible optimisation instead of:
if (data.currentUser.secondaryServDepts.Where(x => x.Id == dept.servDeptId).Count() > 0)
{
userActions.Add(actionType);
}
Use:
if (data.currentUser.secondaryServDepts.Any(x => x.Id == dept.servDeptId))
{
userActions.Add(actionType);
}
Count will enumerate the entire collection while Any will stop at the first match (since all you need is at least one item)

Saving group of items from a list

What I am trying to accomplish is to group my list by supplier id. Iterate over that list calculate stuff etc and when finished pass that list on to save and clear the list out and start over again. The error is the : "collection was modified enumeration operation may not execute. c#". Now from googling it I'm just suming then pass that group off to save and clear the list rinse and repeat. I thought the clear would empty the list and allow for reuse.
Error - "collection was modified enumeration operation may not execute. c#"
group is grouping the list that is passed in to this method.
I created the count to see how many groups I had(6).
ProcessSpecialOrders receives a grouped list, po and the total.
What happens here is this will process through the first group once. Save to the DB then it will throw the error. If I refresh my page or check the DB I can see grop one has saved.
List<xxxxx> specialOrderList = new List<xxxxx>();
var group = from supplier in list group supplier by supplier.SupplierId;
var count = group.Count();
foreach (var grp in group.ToList())
{
specialOrderList.Clear();
foreach (var g in grp.ToList())
{
var orderItemList = new MOrderItem();
if (g.ItemType == "SD")
{
xxx.Id = 0;
xxx.ItemId = g.Id;
xxx.OnHandQty = g.OnHand;
xxx.ItemNo = g.ItemNumber;
xxx.ThisQty = 0;
xxx.NetCost = itemPrice.Where(x => x.ItemId == g.Id).Sum(l => (decimal?)l.NetCost * 1) ?? 0.0M;
xxx.ExtendedCost = 123.99M;
xxx.OnHandWhenBuildQty = 0;
xxx.OnOrderQty = matcoOrderItem.Where(x => x.ItemId == g.Id).Sum(x => (int?)x.ThisQty) ?? 0;
specialOrderList.Add(orderItemList);
}
}
ProcessSpecialOrders(specialOrderList, poNo, specialOrderTotal);
}

How can I add certain values from one list to another list in .NET

I have created 2 lists in my code. One contains a long lists of employee's first and last names, followed by their index:
public List<Employee> FindTestEmployees()
{
var results = SubmitQuery($#"(Select distinct(E.Badge_Sys_No), E.Emp_Id, E.Last_Nm, E.First_Nm,e.emp_job_func_cd
From Employee E, Employee_Job_Func Ef, Emp_Job_Function_Group_Asgnmt Ejfga
Where .....");
var EmployeeList = new List<Employee>();
for (var i = 0; i < results.Rows.Count; i++)
{
var employee = new Employee();
employee.FirstName = results.Rows[i][3].ToString();
employee.LastName = results.Rows[i][2].ToString();
employee.Index = i;
EmployeeList.Add(employee);
EmployeeList.Add(employee);
}
return EmployeeList;
}
The second is a short list of employees who have reports previously generated for them. This list only contains the employee's first and last names:
public List<Employee> FindIPCREmployees()
{
var results = SubmitQuery($#"(Select E.first_nm, e.last_nm, Ejfga.Emp_Job_Function_Group_Cd,
e.emp_job_func_cd
From Interaction I, Interaction_Activity Ia, Appointment A, Branch B,
Employee E, Employee_Job_Func Ef, Emp_Job_Function_Group_Asgnmt Ejfga
Where .....)");
var IPCREmployeesList = new List<Employee>();
for (var i = 0; i < results.Rows.Count; i++)
{
var employee = new Employee();
employee.FirstName = results.Rows[i][0].ToString();
employee.LastName = results.Rows[i][1].ToString();
IPCREmployeesList.Add(employee);
}
return IPCREmployeesList;
}
What I'm trying to do is create a third list that will contain the first and last names of employees from the second list and the index of that specific employee from the 1st list. The important part being the link between the lists by the name of the employee.
Is there a way of doing this in .NET? If so I would really appreciate the help.
Assuming I'm creating the final list you are looking for correctly:
var employeeList = FindTestEmployees();
var secondList = FindIPCREmployees();
var finalList = employeeList.Join(secondList, a => new {a.FirstName, a.LastName}, b => {b.FirstName, b.LastName}, (a,b) => a);
In this case finalList will be a collection of Employee objects from the first list that had entries with a matching first and last name in your second list. I recommend becoming good friends with LINQ if .NET is where you're spending your time.
I believe you need a Dictionary<Employee,int>:
Dictionary<Employee,int> dict=new Dictionary<Employee,int>();
foreach (var employee in IPCREmployeesList)
{
dict.Add(employee,EmployeeList.IndexOf(employee));
}

Assigning a 'day counter' for objects with DateTime?

I have a list of Order objects with a property OrderDate of type DateTime and I am trying to assign a 'DayCounter' for these objects that represents what order of the day it was, for example one day, I have 5 orders so every order gets a counter from 1 up to 5.
Here is what I tried:
orders.GroupBy(order => order.OrderDate.DayOfYear + order.OrderDate.Year)
.SelectMany(group =>
{
var count = 1;
group.Select(order =>
{
order.DayCounter = count;
count++;
return order;
});
return group;
});
the Order objects I get from this code all have DayCounter of 0
Any help would be appreciated
LINQ is not for modifying data, it is for selecting and projecting data. Your Select never gets run because Select is a lazy method and you never iterate over it. Use a normal foreach instead.
var groups = orders.GroupBy(order => order.OrderDate.Date);
foreach (var grouping in groups)
{
int orderCount = 1;
foreach (var order in grouping)
{
order.DayCounter = orderCount;
orderCount++;
}
}
I also changed your grouping key to be a more reliable seperator OrderDate.Date, your old method would consider days that are a year minus one day apart to be the same day.
Try using the overload of .Select which takes the index as a second parameter.
orders.GroupBy(order => order.OrderDate.DayOfYear + order.OrderDate.Year)
.SelectMany(group =>
{
group.Select((order,idx) =>
{
order.DayCounter = idx + 1;
return order;
});
return group;
});

Getting a single ID from loop using LINQ

I have a method that groups items with the same productID together and then adds their quantity together for items in the shopping cart. Now I am trying to add to it where it also adds the quantity from a page that adds to the cart. So in a call to this method I send the productid and quantity selected by the user to add to the total quantity. But the problem I run into is comparing the productids of the items being sent to this method and the ones being grouped together.
Here is what I have below, the commented parts is what I attempted to do to fix this but found out my thoughts were wrong on it.
double totalQty = 0;
bool isQtyValid = true;
List<ShoppingCartDTO> shoppingList = ShoppingCart.Fetch(string.Format("WHERE SessionID='{0}'", sessionID));
foreach (ShoppingCartDTO temp in shoppingList)
{
var groupList = shoppingList.GroupBy(item => item.ProductID);
foreach (var m in groupList)
{
//var productID = m.Select(p => p.ProductID);
//int prodID = Convert.ToInt32(productID);
//if (ProductID == prodID)
//{
var sum = m.Sum(i => i.Quantity);
totalQty = sum;
//totalQty += qty;
isQtyValid = CheckQty(totalQty, temp.ProductID, temp.CustomerID);
//}
}
}
If anyone can provide some pointers or ideas I would really appreciate it. If it could use more explaining I can do that as well, or if you would like to see more code that I am using I can add that too.
Thank you to anyone that can help.
You grouped by the product ID, so it is the Key of your group:
foreach (var m in groupList)
{
var productID = m.Key;
// The rest of your code.
}

Categories