C
C#2y ago
mr.rendero

✅ LINQ get items with priority

Hello, can I get some assistance with the following issue:
public class Item
{
public string Name { get; set; }
public string Identifier { get; set; }
}
public class Item
{
public string Name { get; set; }
public string Identifier { get; set; }
}
So I have a collection of items (List<Item>) and I need some sort of filtering on them. Lets say we have the following items in the collection: Item 1: Name - Retail Identifier - 001 Item 2: Name - Retail Identifier - 111 Item 3: Name - Hospital Identifier - 111 Item 4: Name - Hospital Identifier - 002 As you can see "Item 2" and "Item 3" have the same Identifier. In those cases where "Identifier" is equal for 2 or more items, I need to take only the one with priority which in my case is "Retail". The final collection that I need to get after filtering is the following: Item 1: Name - Retail Identifier - 001 Item 2: Name - Retail Identifier - 111 Item 3: Name - Hospital Identifier - 002 I'm not sure how to do that with LINQ. Any help will be appreciated, thank you 🙂
8 Replies
Esa
Esa2y ago
Hi, so you can solve this with .GroupBy and .SelectMany() . Are you familiar with those two? After running my linq query on your list my output is:
Name=Retail, Identifier=001
Name=Retail, Identifier=111
Name=Hospital, Identifier=002
Name=Retail, Identifier=001
Name=Retail, Identifier=111
Name=Hospital, Identifier=002
mr.rendero
mr.rendero2y ago
I did some research and thought about using GroupBy but was not sure whether it will change the order of items after grouping. Also I have a lot more other properties and I don't want to use Select after grouping them. Can you show me how you did it :?
Esa
Esa2y ago
Well.. To start with - GroupBy lets you turn a List<item> into a List<List<Item>> basically, where the lists are comprised of items that share identifier. So you could have Retail 001 Retail 111, Hospital 111 Hospital 002 When you have that, it's quite straight forward to add in an if that says "if this list has 2 elements, pick the one that says Retail - otherwise pick only the one item"
mr.rendero
mr.rendero2y ago
ahaaa, I understand, thank you 🙂
Esa
Esa2y ago
I can paste the code if you wanna see, but this is a nice learning exercise to learn SelectMany and GroupBy 🙂
mr.rendero
mr.rendero2y ago
It will be helpful to see it of course, If you don't mind. I also don't have much time to play around with it, thats why I posted here because I'm in a hurry.
Esa
Esa2y ago
public class Item
{
public string Name { get; set; }
public string Identifier { get; set; }

public override string ToString() =>
$"Name={Name}, Identifier={Identifier}";
}

var items = new List<Item>
{
new() { Name = "Retail", Identifier = "001" },
new() { Name = "Retail", Identifier = "111" },
new() { Name = "Hospital", Identifier = "111" },
new() { Name = "Hospital", Identifier = "002" }
};


var list = items
.GroupBy(item => item.Identifier)
.SelectMany(group =>
group.Count() > 1
? group.Where(item => item.Name == "Retail")
: group)
.ToList();

foreach (var item in list)
Console.WriteLine(item);
public class Item
{
public string Name { get; set; }
public string Identifier { get; set; }

public override string ToString() =>
$"Name={Name}, Identifier={Identifier}";
}

var items = new List<Item>
{
new() { Name = "Retail", Identifier = "001" },
new() { Name = "Retail", Identifier = "111" },
new() { Name = "Hospital", Identifier = "111" },
new() { Name = "Hospital", Identifier = "002" }
};


var list = items
.GroupBy(item => item.Identifier)
.SelectMany(group =>
group.Count() > 1
? group.Where(item => item.Name == "Retail")
: group)
.ToList();

foreach (var item in list)
Console.WriteLine(item);
mr.rendero
mr.rendero2y ago
Thank you very much, I might play with it more in saturday and sunday. You are saving my life, thank you very much 🙂