Enumerable 的擴充方法 - Any、All、Except

 

一、Any

namespace ConsoleApp1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            List<string> person = new List<string>() { "Mina", "Mary", "Tina", "Jack", "Jason" };
            if (person.Any(x => x.Contains("i")))
            {
                Console.WriteLine("with i char");
            }
            if (person.Any(x => x.Contains("d")))
            {
                Console.WriteLine("with d char");
            }
        }
    }
}
//output: with i char

集合中只要其中一元素符合條件即為 true

當物件為空集合時,Any() 的判斷也是符合直覺不成立。

 

二、All

namespace ConsoleApp1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            List<string> person = new List<string>() { "Mina", "Mary", "Tina", "Jack", "Jason" };
            if (person.All(x => x.Contains("a")))
            {
                Console.WriteLine("all with a char");
            }
            if (person.All(x => x.Contains("d")))
            {
                Console.WriteLine("all with d char");
            }
            List<string> person2 = new List<string>();
            if (person2.All(x => x.Contains("d")))
            {
                Console.WriteLine("person2 all with d char");
            }
        }
    }
}
//output: all with a char
//output: person2 all with d char

集合中需要所有元素符合條件即為 true,

唯特別注意的是,當物件為空集合時,All() 的判斷會成立。

 

三、Except

namespace ConsoleApp1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            List<int> a = new List<int>() { 0, 1, 2, 3, 4 };
            List<int> b = new List<int>() { 1, 5 };
            List<int> c = new List<int>() { 1, 5 };
            List<int> res1 = b.Except(a).ToList();//output: 5
        }
    }
}

於 b 集合中排除有列在 a 集合裡的所有元素

注意:上述 Except 範例不適用於物件上,

如要比對物件則需自己定義的 IEqualityComparer 物件,如下範例

List<CompareModel> UsersA = new List<CompareModel>();
UsersA.Add(new CompareModel
{
    uId = 1,
    uName = "AAA",
    uAge = 20,
});
UsersA.Add(new CompareModel
{
    uId = 2,
    uName = "BBB",
    uAge = 22,
});
UsersA.Add(new CompareModel
{
    uId = 3,
    uName = "CCC",
    uAge = 26,
});

List<CompareModel> UsersB = new List<CompareModel>();
UsersB.Add(new CompareModel
{
uId = 2,
uName = “BBB”,
uAge = 22,
});
UsersB.Add(new CompareModel
{
uId = 4,
uName = “DDD”,
uAge = 25,
});
UsersB.Add(new CompareModel
{
uId = 6,
uName = “EEE”,
uAge = 27,
});

var diffList = UsersA.Except(UsersB, new DataComparer());
foreach (var item in diffList)
{
Console.WriteLine(item.uId + “-“ + item.uName + “-“ + item.uAge);
}

public class CompareModel
{
public int? uId { get; set; }
public string uName { get; set; }
public int? uAge { get; set; }
}
public class DataComparer : IEqualityComparer<CompareModel>
{
public bool Equals(CompareModel x, CompareModel y)
{
//確認兩個物件的資料是否相同
if (Object.ReferenceEquals(x, y)) return true;
//確認兩個物件是否有任何資料為空值
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
//這邊就依照個人需求比對各個屬性的值,以此範例來說也可以只比對uName或比對uName跟uAge
return x.uId == y.uId
&& x.uName == y.uName
&& x.uAge == y.uAge;
}
public int GetHashCode(CompareModel e)
{
//確認物件是否為空值
if (Object.ReferenceEquals(e, null)) return 0;
//取得uId欄位的HashCode
int uId = e.uId == null ? 0 : e.uId.GetHashCode();
//取得uName欄位的HashCode
int uName = e.uName == null ? 0 : e.uName.GetHashCode();
//取得uAge欄位的HashCode
int uAge = e.uAge == null ? 0 : e.uAge.GetHashCode();
//計算HashCode,因為是XOR所以要全部都是1才會回傳1,否則都會回傳0
return uId ^ uName ^ uAge;
}
}

 

四、Intersect

namespace ConsoleApp1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            List<int> a = new List<int>() { 0, 1, 2, 3, 4 };
            List<int> b = new List<int>() { 9 };
            List<int> c = new List<int>() { 1, 5 };
            List<int> res2 = c.Intersect(a).ToList();//output: 1
        }
    }
}

找出 c 集合 與 a 集合裡共同所擁有的元素

 

參考資料:

Enumerable 類別

[筆記]C# 用Except做差集資料比對 實作紀錄