C# List Join List and Filter from Another List

C# List Join List And Filter From Another List

We just need to first remove dropped subjects from enrolled list. then group by student.
note that we have list for each student, that it has Student and Subject as its fields, we just select the name of first student from each (as they all the same) and join the subjects together.

var result = lstEnrolled.Where(e => !lstDropped.Any(d => d.Student == e.Student && d.Subject == e.Subject))  //omit dropped courses
.GroupBy(x => x.Student) // group results by students
.Select(x => new {
Name = x.First().Student.StudentName.Split(' ').First(),
Subjects = string.Join(", ", x.Select(e => e.Subject))
}).ToArray();

for printing:

foreach(var x in result)
Console.WriteLine($"{x.Name}\t{x.Subjects}");

LIVE DEMO

Linq to join two lists and filter using a value of inner list value

Something like this should do the trick:

var searchByPhone = new List<Tuple<string,string>>();
searchByPhone.Add(Tuple.Create("12324344", "message one"));
searchByPhone.Add(Tuple.Create("45646565", "message two"));
searchByPhone.Add(Tuple.Create("56868675", "message three"));

//you should already have this list populated somehow, i'm declaring it here just for the sake of making the code compile
var clientlist = new List<Client>();

//this list will hold your results
List<ClientObject> resultList = new List<ClientObject>();


searchByPhone.ForEach(tp => resultList.AddRange(
clientlist.Where(cl => cl.phones.Any(ph=>ph.phoneno == tp.Item1)).Select(cl => new ClientObject {id = cl.id, firstname = cl.firstname, lastname = cl.lastname, message = tp.Item2, phonenumber = tp.Item1}).ToList()));

Note: you either need to make the members of client, clientobject and phone classes public, or preferably create public properties to get/set their values.

This will give you a list of ClientObject objects, which contain the id, first and last name from the Client object as well as the appropraite number and message from the searchByPhone tuples.
I think that is what you were after. If not, please clarify your needs and I can adjust the answer

Filter a list based on another list condition

Let's say you have a class like below:

class CustomerInformation
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

As you said, you have two lists, let's say you have two lists like below:

List<CustomerInformation> dbList = new List<CustomerInformation>
{
new CustomerInformation{Id=1, FirstName="Raju", LastName="Ahmed"},
new CustomerInformation{Id=2, FirstName="Tahira", LastName="Biswas"},
new CustomerInformation{Id=3, FirstName="Shohag", LastName="Mia"},
new CustomerInformation{Id=4, FirstName="Saiful", LastName="Islam"}
};

List<CustomerInformation> csutomerList = new List<CustomerInformation>
{
new CustomerInformation{Id=1, FirstName="Raju", LastName="Ahmed"},
new CustomerInformation{Id=2, FirstName="Tahira", LastName="Biswas"},
new CustomerInformation{Id=3, FirstName="Shohag", LastName="Mia"},
new CustomerInformation{Id=4, FirstName="Saiful", LastName="Islam"},
new CustomerInformation{Id=5, FirstName="Anny", LastName="Bishwas"},
new CustomerInformation{Id=6, FirstName="Kabita", LastName="Roy"},
new CustomerInformation{Id=7, FirstName="Zahidul", LastName="Emon"}
};

Now you want to get those DB list that are not present in the customer list with somespecific condition, so just try this:

 var newList = csutomerList.Where(cusItem => !dbList.Any(dbItem => cusItem.Id == dbItem.Id && cusItem.FirstName == dbItem.FirstName && cusItem.LastName == dbItem.LastName));

it will first find out all the data that are present in both lists and then simply deduct them.

Sample Output:

Sample Image

Full code here:

    static void Main(string[] args)
{
AvailableData();
Console.ReadKey();
}

public static void AvailableData()
{
// Create two lists.
List<CustomerInformation> dbList = new List<CustomerInformation>
{
new CustomerInformation{Id=1, FirstName="Raju", LastName="Ahmed"},
new CustomerInformation{Id=2, FirstName="Tahira", LastName="Biswas"},
new CustomerInformation{Id=3, FirstName="Shohag", LastName="Mia"},
new CustomerInformation{Id=4, FirstName="Saiful", LastName="Islam"}
};

List<CustomerInformation> csutomerList = new List<CustomerInformation>
{
new CustomerInformation{Id=1, FirstName="Raju", LastName="Ahmed"},
new CustomerInformation{Id=2, FirstName="Tahira", LastName="Biswas"},
new CustomerInformation{Id=3, FirstName="Shohag", LastName="Mia"},
new CustomerInformation{Id=4, FirstName="Saiful", LastName="Islam"},
new CustomerInformation{Id=5, FirstName="Anny", LastName="Bishwas"},
new CustomerInformation{Id=6, FirstName="Kabita", LastName="Roy"},
new CustomerInformation{Id=7, FirstName="Zahidul", LastName="Emon"}
};


var newList = csutomerList.Where(cusItem => !dbList.Any(dbItem => cusItem.Id == dbItem.Id && cusItem.FirstName == dbItem.FirstName && cusItem.LastName == dbItem.LastName));

foreach (var cust in newList)
{
Console.WriteLine("Customer Id :{0} | Customer Name: {1} | Last Name: {2} ",cust.Id,cust.FirstName,cust.LastName);
}
Console.ReadKey();

}
}

class CustomerInformation
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

Filter Out List with another list using LINQ

You're making a new object and then checking the list to see if that exact object/instance is in it (i.e. because it's an object, it's comparing the reference).

Instead, you need to look for overlapping IDs.

Something like this should work:

List<ServiceItem> serviceItems;
List<ServiceItemDetails> serviceItemDetails;

var result = serviceItemDetails.Where(sid => serviceItems.Any(si => si.ID == sid.ID))

In English: "The collection of ServiceItemDetails where the list of service items has an item with the same ID"

Filter a list by another list C#

If you have a situation like:

List<ItemBO> items;
List<ItemCategoryBO> categories;

and you wish to get all the items that have a category that is in your list of categories, you can use this:

IEnumerable<ItemBO> result = items.Where(item =>
categories.Any(category => category.ItemCategory.equals(item.ItemCategory)));

The Any operator enumerates the source sequence and returns true if any element satisfies the test given by the predicate. In this case, it returns true if the categories list contains an ItemCategoryBO where its ItemCategory string is the same as the item's ItemCategory string.
More information about it on MSDN

How to filter a list based on another list using Linq?

Try this:

var filtered = listOfAllVenues
.Where(x=>!listOfBlockedVenues.Any(y=>y.VenueId == x.Id));

It will get all Venues where Id is not in blockedVenues list

Using C# LINQ to concat a filtered List<object> to List<string>

If names is empty, what you're meant to do is this:

var names = businessNames.Select(item => item.Name).ToList();

Another option is to use the List<T>'s ConvertAll method, like so:

var names = buisnessNames.ConvertAll(item => item.Name);

However, if it may be not empty, you'd need to use an if statement too:

var names = new List<string>();
//some code
if (names.Any())
names.AddRange(/*your selected method*/);
else
names = //your selected method;

C# Linq query to join two lists and assign the result to new list

Based on my understanding of your question, I would like to propose two different approaches to solve it:

  • filtering the items in adGroups before associating the adGroups items with the gwtItems items
  • (filtering the items in gwtItems as you have already done, and then) associating the gwtItems items with the adGroups items

Depending on which variable (adGroups or gwtItems) benefits most from being filtered initially, you may choose which approach fits your use case best.

Filtering the adGroups items, then associating them with the gwtItems items

Here, all applicable items from adGroups are grouped by Sid before each Sid-based grouping is associated with items from gwtItems based on the gwtItem's Sid value. After associating adGroups groupings and gwtItems with equal Sid (and unequal Name, due to the initial filtering of adGroups) using .Join(), we select each associated adGroup and gwtItem pair's adGroup.Name and gwtItem.Id in a tuple and use SelectMany() to flatten the collection (from a IEnumerable<IEnumerable< * >> to a IEnumerable< * >).

public IEnumerable<( string Name, int Id )> GetWorkTeamsWhereChangeName(
IEnumerable<Group> adGroups,
IEnumerable<GuidelinesWorkTeam> gwtItems)
{
return adGroups
.Where(adGroup => gwtItems.Any(gwtItem =>
gwtItem.Sid == adGroup.Sid &&
gwtItem.Name != adGroup.Name))
.GroupBy(adGroup => adGroup.Sid)
.Join(gwtItems,
grouping => grouping.Key,
gwtItem => gwtItem.Sid,
( grouping, gwtItem ) => grouping
.Select(adGroup => ( adGroup.Name, gwtItem.Id )))
.SelectMany(_ => _);
}

Associating the gwtItems items with the adGroups items (after filtering the gwtItems first)

Here, the items from gwtItems are first associated with the items from adGroups based on the Sid property from the respective classes, using .Join() before a tuple containing relevant information is returned from the .Join() operation; then, only the associated items that actually have different names are selected and converted to a simpler tuple.

Your original filtering should possibly be included if it is probable that it will filter out many items from gwtItems; but it shouldn't be necessary to obtain the desired result.

public IEnumerable<( string Name, int Id )> GetWorkTeamsWhereChangeName(
IEnumerable<Group> adGroups,
IEnumerable<GuidelinesWorkTeam> gwtItems)
{
return gwtItems
// Original filtering
.Where(gwtItem => adGroups.Any(adGroup =>
gwtItem.Sid == adGroup.Sid &&
gwtItem.Name != adGroup.Name))
// Association and final filtering
.Join(adGroups,
gwtItem => gwtItem.Sid,
adGroup => adGroup.Sid,
( gwtItem, adGroup ) => (
ChangedName: gwtItem.Name != adGroup.Name,
Name: adGroup.Name,
Id: gwtItem.Id))
.Where(workTeam => workTeam.ChangedName)
.Select(workTeam => ( workTeam.Name, workTeam.Id ));
}


Related Topics



Leave a reply



Submit