简体   繁体   中英

Dropdown Select Distinct based on Text property in a List

I have a requirement that I need to get a list of unique / distinct Items for my dropdown value. See the example below,

Example Data

Id                Text

1                 AAA
2                 BBB
3                 AAA
4                 CCC
5                 BBB

I want the result list should be,

Id                Text

1                 AAA
2                 BBB
4                 CCC

I tried so far

 var Value = (from x in db.Items
                     where ((x.CallNo.StartsWith(q) || x.CallNo.Contains(" " + q)) && (!string.IsNullOrEmpty(x.CallNo)))
                     select new
                     {
                         id = x.Id,
                         text = x.CallNo
                     }).Distinct().ToList();

Meaning, I want the list to distinct based on the Text property. And also, the very first occurrence.

You could simply use GroupBy and First :

var Value = db.Items
    .Where(x => x.CallNo.StartsWith(q) || x.CallNo.Contains(" " + q)) && !string.IsNullOrEmpty(x.CallNo))
    .GroupBy(x => x.CallNo)
    .Select(g => g.First())
    .Select(x => new
        {
            id = x.Id,
            text = x.CallNo
        })
    .ToList();

If you actually want to get distinct objects by multiple properties as your title suggests use an anonymous type in the GroupBy .

.GroupBy(x => new { x.CallNo, x.OtherProperty})

If you want to define groups on multiple properties, here's how:

List<something> myList= employee.GroupBy(p => new {p.employeeId, p.employeeName} )
  .Select(g => g.First())
  .ToList();

Distinct has an overload that takes an IEqualityComparer<TSource> . So you can write a comparer and supply that.
Alternatively, you can write a DistinctBy (extension) method. You can find it in Jon Skeet's MiscUtil library . But you can also easily write it yourself:

public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> source,
    Func<T, TKey> keySelector, IEqualityComparer<TKey> comparer = null)
{
    var found = new HashSet<TKey>(comparer);
    return source.Where(element => found.Add(keySelector(element)));
}

Edit: I actually meant the MoreLinq library , but MiscUtil is useful too.
And note this method is for IEnumerable , not IQueryable .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM