[英]How to remove Distinct values from a list?
我只想使用 LINQ 從列表中刪除不同的值。
我的代碼-
List<MyStudents> studentsList = new List<MyStudents>();
public class MyStudents
{
private string student;
private int age;
public string Student
{
get { return student; }
set { student = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
}
我試過了-
studentsList.RemoveAll(o => o.Student).Distinct();
但這不起作用並顯示錯誤-
無法將 Lambda 表達式轉換為預期委托,因為塊中的某些返回類型不能隱式轉換為委托返回類型
PN:我更喜歡從現有列表中刪除不同的項目,而不是創建具有不同值的新列表
如果您已經為Student
實現了Equals
和GetHashCode
,您可以嘗試Linq GroupBy
后跟SelectMany
:
studentsList = studentsList
.GroupBy(o => o.Student) // Groups of same students
.Where(group => group.Count() >= 2) // Students appear at least twice
.SelectMany(group => group) // Ungroup (flatten) to IEnumerable<Student>
.ToList(); // Materialized as List
如果你還沒有實現Equals
和GetHashCode
你必須發明分組鍵,例如:
studentsList = studentsList
.GroupBy(o => new { // Student are equal if and only if they have same
o.Student.Name, // Name
o.Student.Age, // and Age
})
.Where(group => group.Count() >= 2)
.SelectMany(group => group)
.ToList();
在這種情況下,我建議您使用HashSet 。
請記住始終嘗試將您的數據結構與您要解決的問題相匹配。 考慮一下,你會嘗試用錘子在牆上釘一個螺絲嗎? 當然,這是可能的,但不是最優的。
如果你很難堅持使用 LINQ 和 Lists 來解決這個問題,你可以在你的列表上調用 .Distinct() ,它會返回不同的元素。
首先取所有至少出現兩次的值:
var atLeastTwicePresent = studentsList
.Select(sObj => sObj.Student)
.Where(s => studentsList.Where(sObj => sObj.Student == s).Count() > 1);
然后從這個集合中獲取不同的值:
var distinctAtLeastTwice = atLeastTwicePresent.Distinct().ToList();
並且您的列表中應該有至少出現兩次的 Distinct Student 姓名。
如果您只想讓結果中至少出現兩次的學生,請嘗試將它們分組並根據計數過濾組:
studentsList.GroupBy(s => s.Student).Where(g => g.Count() > 1).Select(g => g.First())
或者
from s in studentsList
group s by s.Student into g
where g.Count() > 1
select g.First()
您需要按所需的鍵對項目進行分組。 使用new { }
,您可以使用 linq 組創建密鑰。 然后,不要選擇組中的第一個密鑰(這是一個匿名的 class,您不想要) ,而是選擇 select。
匿名 class 的想法是,組比較所有屬性,所以它可以是組。 (這就是為什么你不能在 MyStudents 課上分組)
你可以試試這個:
using System;
using System.Collections.Generic;
using System.Linq;
public class MyStudents
{
private string student;
private int age;
public string Student
{
get { return student; }
set { student = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
}
public class Program
{
public static void Main()
{
// some testdata...
var students = new List<MyStudents>
{
new MyStudents { Student = "John", Age = 17 },
new MyStudents { Student = "Mary", Age = 18 },
new MyStudents { Student = "John", Age = 17 },
new MyStudents { Student = "Hank", Age = 20 },
};
var newList = students
// The whole idea is, group the list by creating a key.
.GroupBy(o => new {o.Student, o.Age})
// you don't want to select the key, because it's an anonymous class
// So select the first item which was added to the group.
.Select(o => o.First())
// create a new list.
.ToList();
// present them
foreach(var s in newList)
Console.WriteLine("Student: "+s.Student+", Age: "+s.Age);
}
}}
這是一個dotnetfiddle
這是一個示例:使用 list.Distinct().ToList();
// List with duplicate elements.
List<int> list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(3);
list.Add(4);
list.Add(4);
list.Add(4);
foreach (int value in list)
{
Console.WriteLine("Before: {0}", value);
}
// Get distinct elements and convert into a list again.
List<int> distinct = list.Distinct().ToList();
foreach (int value in distinct)
{
Console.WriteLine("After: {0}", value);
}
}
對類使用.destinct 需要比較器方法:請參見此處。 但它必須是 IEqualityComparer 的一個實例!
class ProductComparer : IEqualityComparer<Product>
{
public bool Equals(Product x, Product y) {
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x.Make == y.Make && x.Model == y.Model;
}
public int GetHashCode(Product product) {
if (Object.ReferenceEquals(product, null)) return 0;
int hashProductName = product.Make == null ? 0 : product.Make.GetHashCode();
int hashProductCode = product.Model.GetHashCode();
return hashProductName ^ hashProductCode;
}
}
**The Distinct operator has an overload method that lets you pass an instance of IEqualityComparer.** So for this approach we created a class “ProductComparer” that implements the IEqualityCompaper. Here’s the code to use it:
if (!IsPostBack) {
GridView1.DataSource = GetProducts()
.Distinct(new ProductComparer());
GridView1.DataBind();
}
如果您想獲得所有獨特的 Student,那么您只需要將 select 與您的列表不同。
像這樣:studentList.DistinctBy(x => x.id);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.