I have a class, I am using list to get (assigning multiple list entry values in c#).
// This will return me more than 1 records.
List<ClassEmpInfo> employeeDetails =GetEmployeeInformation();
List<ClassEmployee> empInfo = null;
foreach (ClassEmployee employee in employeeDetails)
{
//This needs to show all the ids belonging to employeeDetails.
//If there are 3 different employee ids ,
//the list empInfo should hold the output of all the 3,
//but i am getting the last 3rd one alone.
//How to cumulatively add 3 different employee ids.
empInfo = GetEmployeeDetails(Id, EmpId);
}
I am getting the last employee information rather than all the employee details in the empInfo list.
If the type is string I can do something like:
if (strType.Length > 0)
{
strType = strType + returned values;
}
else
{
strType = strType;
}
How do I add the list values cumulatively?
I think what you want to do is the following:
List empInfo = new List<detail_type>(); // whatever type is returned by GetEmployeeDetails
foreach (ClassEmployee employee in employeeDetails)
{
empInfo.Add(GetEmployeeDetails(id, EmpId));
}
It's rather unclear to me, though, if GetEmployeeDetails returns a single value or a list of values. If it returns a list of values, then change the line in the loop to:
empInfo.AddRange(GetEmployeeDetails(id, EmpId));
You add stuff to a list with .Add() this is per definition cumulative.
Related
I have a list of object. I want to group this list from two columns and get the last value of this column.
I also want to have the entire copy of the object.
I have write this code:
var FileDaInviare = info.FNAVB00R.ToList();
var FileDaInvNew = from c in FileDaInviare
group c by new
{
c.Progressivo_Gemap,
c.Committente_Gemap,
} into gcs
select new FNAVB00R()
{
};
FileDaInvNew = FileDaInvNew.ToList();
But with this code i have only the first value of the group by(I want the last) and the object is empty. I want copy of the entire object directly please consists of hundred columns.
Thanks to all
You could use Last extension method.
FileDaInvNew = FileDaInviare.GroupBy(g=> new {g.Progressivo_Gemap, g.Committente_Gemap})
.Select(x=>x.Last())
.ToList()
i have one list object which contains int like below:
var list = new List<int>();
var ids=getting only ids from database.for Eg:1,2,1,3,5,6,3.
Now what i want to do is after fetching ids from datatabase i want to add in to my list object and if any differnt ids is added(eg:ids:2) then i want to break from the loop.
For Ex: After adding 1 in my list now if i try to add 2 which doesnt exist in my list object then i want to break from my loop with status different element found outside the loop.
Add values in the list object till duplicate value is found means add only duplicate values in my list object and if distinct value is found which is not already in the list then break from loop.Break from the loop after adding 1 in list because 2 is different and it is not already in the list object.
This is my code:
bool status;
for (var i = 0; i < ids.Count; i++)
{
list.Add(ids);
}
//here i want status with different element found or not
Note:I just want to add only duplicates values in my list object until new id is found.
i just want to add duplicate values in list object until different ids is found.
var list = new List<int>{ 1, 2, 3, 4};
var idsFromDb = new List<int> {1, 2, 5, 3};
foreach (int id in idsFromDb)
{
if (list.Contains(id))
{
break;
}
list.Add(id);
}
You can use foreach to iterate over elements of ids
break works in foreach just the way it does in for
if we don't break, do whatever you want to do, for example, add the value to list
Contains checks if list already contains id.
This makes it roughly an O(n^2) operation - because both foreach and Contains iterate over elements of list
Code:
foreach (var id in ids)
{
if (list.Contains(id))
{
break;
}
list.Add(id);
}
You can use Contains
status = false;
for (var i = 0; i < ids.Count; i++)
{
if (list.Count > 0 && !list.Contains(ids[i])){
list.Add(ids[i]); //add this, be it duplicate or not
status = true; //different element found
break; //break if this is not duplicate
} else {
//do something for duplicate
list.Add(ids[i]); //add this, be it duplicate or not
}
}
Contains can check if your item already exists in the List
Here's your desired HashSet<T> + LINQ approach:
var dupChecker = new HashSet<int> {ids[0]}; // add first element, now only duplicates are allowed
List<int> dupList = ids.TakeWhile(i => !dupChecker.Add(i)).ToList();
I'm working on creating a filter for a collection of employees. In order to do this I initially fetch a raw collection of all employees. I clone this list so I can iterate over the original list but remove items from the second list.
For each filter I have, I build a collection of employee ids that pass the filter. Having gone through all filters I then attempt to remove everything that isn't contained in any of these lists from the cloned list.
However for some reason, whenever I attempt to do this using .RemoveAll(), all records seemed to be removed and I can't figure out why.
Here is a stripped down version of the method I'm using, with only 1 filter applied:
public List<int> GetFilteredEmployeeIds(int? brandId)
{
List<int> employeeIds = GetFilteredEmployeeIdsBySearchTerm();
List<int> filteredEmployeeIds = employeeIds.Clone();
// Now filter the results based on which checkboxes are ticked
foreach (var employeeId in employeeIds)
{
// 3rd party API used to get values - please ignore for this example
Member m = new Member(employeeId);
if (m.IsInGroup("Employees"))
{
int memberBrandId = Convert.ToInt32(m.getProperty("brandID").Value);
// Filter by brand
List<int> filteredEmployeeIdsByBrand = new List<int>();
if (brandId != null)
{
if (brandId == memberBrandId)
filteredEmployeeIdsByBrand.Add(m.Id);
var setToRemove = new HashSet<int>(filteredEmployeeIdsByBrand);
filteredEmployeeIds.RemoveAll(x => !setToRemove.Contains(x));
}
}
}
return filteredEmployeeIds;
}
As you can see, I'm basically attempting to remove all records from the cloned record set, wherever the id doesn't match in the second collection. However for some reason every record seems to be getting removed.
Anybody know why?
P.S: Just to clarify, I have put in logging to check the values throughout the process and there are records appearing in the second list, however for whatever reason they're not getting matched in the RemoveAll()
Thanks
Ok only minutes after posting this I realised what I did wrong: The scoping is incorrect. What it should've been was like so:
public List<int> GetFilteredEmployeeIds(int? brandId)
{
List<int> employeeIds = GetFilteredEmployeeIdsBySearchTerm();
List<int> filteredEmployeeIds = employeeIds.Clone();
List<int> filteredEmployeeIdsByBrand = new List<int>();
// Now filter the results based on which checkboxes are ticked
foreach (var employeeId in employeeIds)
{
Member m = new Member(employeeId);
if (m.IsInGroup("Employees"))
{
int memberBrandId = Convert.ToInt32(m.getProperty("brandID").Value);
// Filter by brand
if (brandId != null)
{
if (brandId == memberBrandId)
filteredEmployeeIdsByBrand.Add(m.Id);
}
}
}
var setToRemove = new HashSet<int>(filteredEmployeeIdsByBrand);
filteredEmployeeIds.RemoveAll(x => !setToRemove.Contains(x));
return filteredEmployeeIds;
}
Essentially the removal of entries needed to be done outside the loop of the employee ids :-)
I know that you said your example was stripped down, so maybe this wouldn't suit, but could you do something like the following:
public List<int> GetFilteredEmployeeIds(int? brandId)
{
List<int> employeeIds = GetFilteredEmployeeIdsBySearchTerm();
return employeeIds.Where(e => MemberIsEmployeeWithBrand(e, brandId)).ToList();
}
private bool MemberIsEmployeeWithBrand(int employeeId, int? brandId)
{
Member m = new Member(employeeId);
if (!m.IsInGroup("Employees"))
{
return false;
}
int memberBrandId = Convert.ToInt32(m.getProperty("brandID").Value);
return brandId == memberBrandId;
}
I've just done that off the top of my head, not tested, but if all you need to do is filter the employee ids, then maybe you don't need to clone the original list, just use the Where function to do the filtering on it directly??
Please someone let me know if i've done something blindingly stupid!!
Still a beginner so please bare with them me on this. I would like the ability to add a number value to my property after the list distinguishes that there are duplicate values.
For example, two users have inputted into the system that they have the same employee ID of 001, the List allows them both to go in then applies a condition to check the list for any duplicates so in this case there would be. Now this conditional is true, add 1 to that property so the last employee now has employee ID of 002.
I believe LINQ will more than likely be involved in this process, but not to sure on how to go about this. I understand I will also have to update my List after performing this after to maintain the properties state throughout the program.
Thanks in advance hope everything is clear, question again How to add value to a property within a List<>
Code Snippet below.
Employee = new Employee(employeeFirstName, employeeLastName,001); // Hard coded for sake of example.
EmployeeList.AddEmployee(Employee);
EmployeeList Class
public static void AddEmployee(Employee employee)
{
employees.Add(new Employee(employee.FirstName,employee.LastName,employee.EmployeeID));
employees.Add(new Employee("John", "Jones", 001));
}
public void employeeIdValidation()
{
if (employees.Count() != employees.Select(x => new {staffId = x.EmployeeID }).Distinct().Count())
{
Console.WriteLine("Every Book and Category should be unique");
// employee ID increments by 1
// update List
}
else
{
Console.WriteLine("No duplicate found");
}
}
public static List<Employee> GetEmployeeList()
{
return employees; // With the updated EmployeeID
}
IMHO, you should use a Dictionary<int, Employee> (where the key is the Id) instead of a list. This will force you to update the ID of a duplicate record before adding to the collection and save a whole bunch of trouble and computation.
To find in your list what Employees have the same Id you can use this linq function.
var result=employees.ToLookup(e => e.Id);
At this way you can group the employees that have the same Id. Then, you can iterate for each group of employees with the same id as I show you below:
foreach (IGrouping<int, Employee> group in result)
{
//More than 2 employees with the same Id
if (group.Count()>1)
{
foreach (Employee employee in group)
{
//Change your ids here
}
}
}
[Update 1]:
To change the Ids I proporse you find first the max id before iterate in the groups.
int nextID = result.Max(e => e.Key)+1;
Then, change the second foreach cycle for a for cycle as you can see below. When you find a group with more than two Employees with the same id, don't change the first element, change the rest at this way:
//The first element don't change the id, start for the second element
for (int j = 1; j < group.Count(); j++)
{
var currentEmployee=group.ElementAt(j);
// Change the id and refresh the nextID variable
currentEmployee.Id = nextID++;
}
I have an accordion that binds data for each item from an array.
I want that for every time that I bound the data I will loop through all of the array and aggregate all of the items with the same id and create a long string with a name from a cell. In the code the name oneJob.order_id does not exist and I don't know why.
protected string GetAllProffesions(int orderID)
{
IEnumerable<string> allProf;
orderID = 544;
Job[] curItems = null;
curItems = JobManager.GetJobs(RangeID, GetParam());
allProf = from oneJob in curItems
where oneJob.order_id == orderID
select oneJob.profession_name;
return Convert.ToString(allProf);
}
This is because your job class doesn't have a property called order_id. Check your spelling.
Also, you probably don't want to do Convert.ToString(allProf), as I expect this will give you the type name instead of all the professions concatenated. Try this instead:
string.Join(", ", allProf.ToArray());