Remove duplicate by matching string part of text

Viewed 81

Check the code bellow. Here i am creating a method that simply should remove the duplicate from the list foo. If you see the list values they are product id and quantity derived by : so the first part of number before : is product and and second part of number after : is the product quantity. I am taking this list into RemoveDuplicateItems() method for processing. This method should remove all matching product id items from whole list but my current method just returns exactly same list which i am taking on input. How can i fix my method to remove those item from list which has matching first part number. (first part number means before :)

The final output on doo variable it should remove the first from from list which is 22:15 since it has matching with second one.

C#:

[HttpPost]
public JsonResult DoSomething()
{

    var foo = new List<string>();
    foo.Add("22:10");//this should removed by RemoveDuplicateItems() since it has `22` matching with second one
    foo.Add("22:15");
    foo.Add("25:30");
    foo.Add("26:30");

    var doo = RemoveDuplicateItems(foo);

    return Json("done");
}

public List<string> RemoveDuplicateItems(List<string> AllItems)
{
    var FinalList = new List<string>();

    var onlyProductIds = new List<string>();
    foreach (var item in AllItems)
    {
        Match result = Regex.Match(item, @"^.*?(?=:)");
        onlyProductIds.Add(result.Value);
    }
    var unique_onlyProductIds = onlyProductIds.Distinct().ToList();
    foreach (var item in AllItems)
    {
        Match result = Regex.Match(item, @"^.*?(?=:)");
        var id = unique_onlyProductIds.Where(x => x.Contains(result.Value)).FirstOrDefault();
        if (id != null)
        {
            FinalList.Add(item);
        }
    }
    return FinalList;
}
3 Answers

There are multiple ways to achieve this, one is, as suggested by @Aluan Haddad is to use Linq. His comment uses the query syntax but would could use the method syntax too (I assumed you use C#8):

List<string> doo = foo.GroupBy(str => str[0..2])
                      .Select(entry => entry.Last())
                      .ToList();

Note that this works because the current implementation of GroupBy preserves ordering.

Does this work for you?

List<string> doo =
    foo
        .Select(x => x.Split(':'))
        .GroupBy(x => x[0], x => x[1])
        .Select(x => $"{x.Key}:{x.Last()}")
        .ToList();

you can do it using Linq :

var doo = foo.Select(x =>
{
    var split = x.Split(':');
    return new { Key = split[0], Value = split[1] };
})
.GroupBy(x => x.Key)
.OrderBy(x => x.Key)
.Select(x =>
    {
        var max = x.LastOrDefault();
        return $"{max.Key}:{max.Value}";
    }
).ToList();
Related