web-dev-qa-db-fra.com

Requête Linq pour obtenir les valeurs distinctes dans une liste

Supposons que ce soit ma classe de membre

class Member 
{
    public string CategoryId { get; set; }
    public string MemberName { get; set; }
    public int Distance { get; set; }
}

Et, c'est la liste.

var list = new List<Member>();
list.Add(new { CategoryId = "01", MemberName="andy" Distance=3});
list.Add(new { CategoryId = "02", MemberName="john" Distance=5});
list.Add(new { CategoryId = "01", MemberName="mathew" Distance=7});
list.Add(new { CategoryId = "03", MemberName="bakara" Distance=2});

Quelqu'un peut-il s'il vous plaît suggérer la logique/requête linq pour obtenir la liste ayant categoryID distinct/unique avec la plus courte distance.

La output devrait être:

list.Add(new { CategoryId = "01", MemberName="andy" Distance=3});
list.Add(new { CategoryId = "02", MemberName="john" Distance=5});
list.Add(new { CategoryId = "03", MemberName="bakara" Distance=2});
8
PaRsH

Cela devrait vous donner ce dont vous avez besoin:

var grouped = list.GroupBy(item => item.CategoryId);
var shortest = grouped.Select(grp => grp.OrderBy(item => item.Distance).First());

Il regroupe d’abord les éléments avec la même CategoryId, puis sélectionne le premier de chaque groupe (classé par Distance). 

22
Kjartan

Ceci est similaire à ceux ci-dessus, mais c'est techniquement un one liner pour ceux qui sont intéressés ....

var queryResult= (from l in list
                  select new Member()
                 { 
                    CategoryId = l.CategoryId , 
                    MemberName = l.MemberName 
                    Distance = l.Distance
                 }).GroupBy(x=>x.CatagoryId).Select(z=>z.OrderBy(i=>i.Distance).First()).ToList();
4
Mike T

Vous pouvez utiliser le code suivant: 

List<Member> sourceList = new List<Member>();
IEnumerable<Member> result = 
    (sourceList as IEnumerable<Member>)
    .Distinct()
    .OrderBy(value => value.CategoryId);

Groupez la liste en catégories, puis triez chaque groupe en fonction de la distance, en prenant le premier élément (la distance la plus faible). Projetez les résultats dans une nouvelle collection Member.

var query = from member in list 
            group member by member.CategoryId into memberGrouping
            let groupedMember = memberGrouping.OrderBy (mg => mg.Distance).First() 
            select new Member()
            { 
              CategoryId = memberGrouping.Key, 
              MemberName = groupedMember.MemberName, 
              Distance = groupedMember.Distance 
            };
1
asawyer

essaye ça

var distinctIds = list.Distinct(item => item.CategoryId).ToList();
var newList = new List<Member>();
foreach(var id in distinctIds){
      newList.Add(list.Where(item => item.CategoryId == id).Min(item => item.Distance))
}
newList.OrderBy(item => item.CategoryId);
0
Ravi
class Member {
    public string CategoryId {get; set;}
    public string MemberName{get; set;}
    public int Distance{get; set;}
}

var list = new List<Member>();
list.Add(new Member{ CategoryId = "01", MemberName="andy", Distance=3});
list.Add(new Member{ CategoryId = "02", MemberName="john", Distance=5});
list.Add(new Member{ CategoryId = "01", MemberName="mathew", Distance=7});
list.Add(new Member{ CategoryId = "03", MemberName="bakara", Distance=2});

var query = list.GroupBy(member => member.CategoryId).Select(x=>x.OrderBy(y=>y.Distance).First());
0
Original10

Cela fonctionne aussi, si vous n'avez pas besoin d'articles commandés par (peu modifié réponse de Kjartan )

var grouped = list.GroupBy(item => item.CategoryId).ToList();
var shortest = grouped.Select(grp => grp.OrderBy(item => item.Distance).First());
0
Aamol