class obj
{
int typeId; //10 types 0-9
string uniqueString; //this is unique
}
Supposons qu'il existe une liste avec 100 éléments d'obj, mais seulement 10 ID de type uniques.
Est-il possible d'écrire une requête LINQ renvoyant les 10 entiers uniques de la liste des objs?
Réponses:
la source
En supposant que vous vouliez l'objet complet, mais que vous ne vouliez traiter que de la distinction
typeID
, rien n'est intégré à LINQ pour vous faciliter la tâche. (Si vous voulez juste lestypeID
valeurs, c'est facile - projetez-y avecSelect
, puis utilisez l'Distinct
appel normal .)Dans MoreLINQ, nous avons l'
DistinctBy
opérateur que vous pouvez utiliser:var distinct = list.DistinctBy(x => x.typeID);
Cela ne fonctionne que pour LINQ to Objects.
Vous pouvez utiliser un regroupement ou une recherche, c'est juste un peu ennuyeux et inefficace:
var distinct = list.GroupBy(x => x.typeID, (key, group) => group.First());
la source
Si vous souhaitez simplement utiliser Linq pur, vous pouvez utiliser groupby:
Si vous souhaitez qu'une méthode soit utilisée dans toute l'application, similaire à ce que fait MoreLinq :
public static IEnumerable<TSource> DistinctBy<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) { HashSet<TKey> seenKeys = new HashSet<TKey>(); foreach (TSource element in source) { if (!seenKeys.Contains(keySelector(element))) { seenKeys.Add(keySelector(element)); yield return element; } } }
En utilisant cette méthode pour trouver les valeurs distinctes en utilisant uniquement la propriété Id, vous pouvez utiliser:
var query = objs.DistinctBy(p => p.TypeId);
vous pouvez utiliser plusieurs propriétés:
var query = objs.DistinctBy(p => new { p.TypeId, p.Name });
la source
Bien sûr, utilisez
Enumerable.Distinct
.Étant donné une collection de
obj
(par exemplefoo
), vous feriez quelque chose comme ceci:var distinctTypeIDs = foo.Select(x => x.typeID).Distinct();
la source
Je pense que c'est ce que vous recherchez:
var objs= (from c in List_Objects orderby c.TypeID select c).GroupBy(g=>g.TypeID).Select(x=>x.FirstOrDefault());
Similaire à celui-ci Renvoyer un IQueryable distinct avec LINQ?
la source
.First
c'est bien, puisque vous n'auriez pas le groupe s'il n'y avait pas quelque chose dedans.GroupBy
pour rendre cela plus simple - voir ma réponse pour un exemple.Si vous souhaitez simplement utiliser Linq, vous pouvez remplacer les méthodes Equals et GetHashCode .
Classe de produit :
public class Product { public string ProductName { get; set; } public int Id { get; set; } public override bool Equals(object obj) { if (!(obj is Product)) { return false; } var other = (Product)obj; return Id == other.Id; } public override int GetHashCode() { return Id.GetHashCode(); } }
Méthode principale :
static void Main(string[] args) { var products = new List<Product> { new Product{ ProductName="Product 1",Id = 1}, new Product{ ProductName="Product 2",Id = 2}, new Product{ ProductName="Product 4",Id = 5}, new Product{ ProductName="Product 3",Id = 3}, new Product{ ProductName="Product 4",Id = 4}, new Product{ ProductName="Product 6",Id = 4}, new Product{ ProductName="Product 6",Id = 4}, }; var itemsDistinctByProductName = products.Distinct().ToList(); foreach (var product in itemsDistinctByProductName) { Console.WriteLine($"Product Id : {product.Id} ProductName : {product.ProductName} "); } Console.ReadKey(); }
la source
Je voulais lier une donnée particulière à la liste déroulante et elle devrait être distincte. J'ai fait ce qui suit:
List<ClassDetails> classDetails; List<string> classDetailsData = classDetails.Select(dt => dt.Data).Distinct.ToList(); ddlData.DataSource = classDetailsData; ddlData.Databind();
Voyez si ça aide
la source