Rasme
Rasme

Reputation: 53

How to edit duplicates in a List?

I'm using a DropDownList with cId (course id) and cName (course name). However, if there's a duplicated cName, I would like to join startDate with the cName. Like: $"cName ({startDate})"

This is how my list look like:

var list = new List<(int cId, string cName, string startDate)>
{
    (1, "Math", "1/12"),
    (2, "Music", "1/12"),
    (3, "English", "1/12"),
    (4, "English", "11/4"),
    (5, "Swedish", "1/12"),
    (6, "Russia", "1/12")
};

Since there's two cName with English, startDate should be added into it's string, like:

cId    cName
----   -----
 1   | "Math"
 2   | "Music"
 3   | "English (1/12)"
 4   | "English (11/4)"
 6   | "Swedish"
 7   | "Russia"

What I had in mind:

if the list have any duplicated cName, cName = $"cName ({startDate})"

EDIT:

This is how the list is added into the DropDownList:

foreach (var item in list)
      {
           dplCourse.Items.Add(new ListItem(item.cId, item.cName));
      }

Upvotes: 1

Views: 77

Answers (3)

Sefe
Sefe

Reputation: 14007

You can use LINQ to get the display names. You can group the items, check the number of items in the group and unroll the groups back into a flat list of items. Since you have an ID, you can order the items accordingly (the grouping messes up the order).

This all would look like this:

var listItemsQry =
    from item in list
    group item by item.cName into itemGrp
    let itemCount = itemGrp.Count()
    from groupedItem in itemGrp
    orderby groupedItem.cId
    let itemName = itemCount > 1 ?
        $"{groupedItem.cName} {groupedItem.startDate}" :
        groupedItem.cName
    select new ListItem(item.cId, itemName);

foreach(ListItem item in listItemsQry) {
    dplCourse.Items.Add(item);
}

Upvotes: 2

Scott Chamberlain
Scott Chamberlain

Reputation: 127593

You will need to do a pass over the list to find which ones are duplicates and change the name of the duplicates before you add them to the display list.

var list = new List<(int cId, string cName, string startDate)>
{
    (1, "Math", "1/12"),
    (2, "Music", "1/12"),
    (3, "English", "1/12"),
    (4, "English", "11/4"),
    (5, "Swedish", "1/12"),
    (6, "Russia", "1/12")
};

var duplicates = new HashSet<string>(
            list.GroupBy(x => x.cName) //Group the items by name
                .Where(g => g.Count() > 1) //Find groups with more than 1
                .Select(g => g.Key)); //Just add the names to the HashSet, not the group

foreach (var item in list)
{
     var displayName = item.cName
     if(duplicates.Contains(displayName))
     {
         displayName += $" ({item.startDate})";
     }
     dplCourse.Items.Add(new ListItem(item.cId, displayName));
}

Upvotes: 6

ppenchev
ppenchev

Reputation: 157

The most simplest and not so smart solution you can use is to make a list with those items, which are unique. You can achieve it as for example in that foreach use a condition if cName already exists in the temp list with unique values. After that to make a new second temp list with those items which has duplications and to put all of them as cName + startDate. Finally you can merge both temp list in a final one.

Upvotes: 0

Related Questions