class obj
{
int typeId; //10 types 0-9
string uniqueString; //this is unique
}
Asumsikan ada daftar dengan 100 elemen obj, tetapi hanya 10 typeID unik.
Apakah mungkin untuk menulis query LINQ mengembalikan 10 int unik dari daftar obj?
class obj
{
int typeId; //10 types 0-9
string uniqueString; //this is unique
}
Asumsikan ada daftar dengan 100 elemen obj, tetapi hanya 10 typeID unik.
Apakah mungkin untuk menulis query LINQ mengembalikan 10 int unik dari daftar obj?
Jawaban:
objList.Select(o=>o.typeId).Distinct()
Dengan asumsi Anda menginginkan objek penuh, tetapi hanya ingin berurusan dengan perbedaan typeID
, tidak ada yang dibangun ke dalam LINQ untuk membuatnya mudah. (Jika Anda hanya menginginkan typeID
nilainya, mudah - proyeksikan itu dengan Select
dan kemudian gunakan Distinct
panggilan normal .)
Di MoreLINQ kami memiliki DistinctBy
operator yang dapat Anda gunakan:
var distinct = list.DistinctBy(x => x.typeID);
Ini hanya berfungsi untuk LINQ ke Objek.
Anda dapat menggunakan pengelompokan atau pencarian, ini hanya agak mengganggu dan tidak efisien:
var distinct = list.GroupBy(x => x.typeID, (key, group) => group.First());
Jika hanya ingin menggunakan Linq murni, Anda dapat menggunakan groupby:
List<obj> distinct =
objs.GroupBy(car => car.typeID).Select(g => g.First()).ToList();
Jika Anda ingin metode digunakan di seluruh aplikasi, mirip dengan yang dilakukan 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;
}
}
}
Dengan menggunakan metode ini untuk menemukan nilai yang berbeda hanya dengan menggunakan properti Id, Anda dapat menggunakan:
var query = objs.DistinctBy(p => p.TypeId);
Anda dapat menggunakan beberapa properti:
var query = objs.DistinctBy(p => new { p.TypeId, p.Name });
Tentu, gunakan Enumerable.Distinct
.
Diberikan koleksi obj
(mis. foo
), Anda akan melakukan sesuatu seperti ini:
var distinctTypeIDs = foo.Select(x => x.typeID).Distinct();
Saya pikir inilah yang Anda cari:
var objs= (from c in List_Objects
orderby c.TypeID select c).GroupBy(g=>g.TypeID).Select(x=>x.FirstOrDefault());
Mirip dengan Returning a Distinct IQuerizable with LINQ?
.First
baik-baik saja, karena Anda tidak akan memiliki grup jika tidak ada sesuatu di dalamnya.
GroupBy
untuk membuat ini lebih sederhana juga - lihat jawaban saya sebagai contoh.
Jika hanya ingin menggunakan Linq, Anda dapat mengganti metode Equals dan GetHashCode .
Kelas produk :
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();
}
}
Metode Utama :
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();
}
Saya ingin mengikat data tertentu ke dropdown dan itu harus berbeda. Saya melakukan hal berikut:
List<ClassDetails> classDetails;
List<string> classDetailsData = classDetails.Select(dt => dt.Data).Distinct.ToList();
ddlData.DataSource = classDetailsData;
ddlData.Databind();
Lihat apakah itu membantu