class obj
{
int typeId; //10 types 0-9
string uniqueString; //this is unique
}
Suponha que haja uma lista com 100 elementos de obj, mas apenas 10 typeIDs exclusivos.
É possível escrever uma consulta LINQ para retornar os 10 ints exclusivos da lista de objs?
Respostas:
fonte
Supondo que você deseja o objeto completo, mas deseja apenas lidar com a distinção por
typeID
, não há nada integrado ao LINQ para tornar isso fácil. (Se você deseja apenas ostypeID
valores, é fácil - projete com base nissoSelect
e use aDistinct
chamada normal .)Em MoreLINQ , temos o
DistinctBy
operador que você pode usar:var distinct = list.DistinctBy(x => x.typeID);
No entanto, isso só funciona para LINQ to Objects.
Você pode usar um agrupamento ou pesquisa, é apenas um pouco irritante e ineficiente:
var distinct = list.GroupBy(x => x.typeID, (key, group) => group.First());
fonte
Se quiser apenas usar o Linq puro, você pode usar groupby:
Se você quiser que um método seja usado em todo o aplicativo, semelhante ao que MoreLinq faz:
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; } } }
Usando este método para encontrar os valores distintos usando apenas a propriedade Id, você pode usar:
var query = objs.DistinctBy(p => p.TypeId);
você pode usar várias propriedades:
var query = objs.DistinctBy(p => new { p.TypeId, p.Name });
fonte
Claro, use
Enumerable.Distinct
.Dada uma coleção de
obj
(por exemplofoo
), você faria algo assim:var distinctTypeIDs = foo.Select(x => x.typeID).Distinct();
fonte
Acho que é isso que você está procurando:
var objs= (from c in List_Objects orderby c.TypeID select c).GroupBy(g=>g.TypeID).Select(x=>x.FirstOrDefault());
Semelhante a este Retornando um IQueryable distinto com LINQ?
fonte
.First
está bem, já que você não teria o grupo se não houvesse algo nele.GroupBy
para tornar isso mais simples também - veja minha resposta para um exemplo.Se quiser apenas usar o Linq, você pode substituir os métodos Equals e GetHashCode .
Classe de produto :
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étodo Principal :
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(); }
fonte
Eu queria vincular um dado específico ao menu suspenso e ele deveria ser distinto. Eu fiz o seguinte:
List<ClassDetails> classDetails; List<string> classDetailsData = classDetails.Select(dt => dt.Data).Distinct.ToList(); ddlData.DataSource = classDetailsData; ddlData.Databind();
Veja se ajuda
fonte