LINQ之Distinct

返回LINQ大全首页

Distinct()

返回序列中的非重复元素。
MSDN

using System.Linq;
using System.Collections;
using System.Collections.Generic;

public static class Program
{

    static void Main( string[] args )
    {
        int[]       dataA   = new int[]         { 0, 1, 3, 3, 2 };
        List<float> dataB   = new List<float>() { 1.5f, 1.5f, 1.5f, 1.5f };
        string[]    dataC   = new string[]      { "征史郎", "征四郎", "征史郎", "正史郎" };

        IEnumerable<int>    dataA_D = dataA.Distinct();
        IEnumerable<float>  dataB_D = dataB.Distinct();
        IEnumerable<string> dataC_D = dataC.Distinct();

        System.Console.WriteLine( "dataA         :{0}", dataA.Text() );
        System.Console.WriteLine( "dataA Distinct:{0}", dataA_D.Text() );
        System.Console.WriteLine( "dataB         :{0}", dataB.Text() );
        System.Console.WriteLine( "dataB Distinct:{0}", dataB_D.Text() );
        System.Console.WriteLine( "dataC         :{0}", dataC.Text() );
        System.Console.WriteLine( "dataC Distinct:{0}", dataC_D.Text() );

        System.Console.ReadKey();
    }

    public static string Text( this IEnumerable i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
}

dataA :[0], [1], [3], [3], [2],
dataA Distinct:[0], [1], [3], [2],
dataB :[1.5], [1.5], [1.5], [1.5],
dataB Distinct:[1.5],
dataC :[征史郎], [征四郎], [征史郎], [正史郎],
dataC Distinct:[征史郎], [征四郎], [正史郎],

上面的示例用的是值类型,那么引用类型呢?

using System.Linq;
using System.Collections;
using System.Collections.Generic;

public static class Program
{
    private class Parameter
    {
        public string   Name    { get; set; }
        public int      Age     { get; set; }
        
        public override string ToString()
        {
            return string.Format( "Name:{0}, Age:{1}", Name, Age );
        }
    }

    static void Main( string[] args )
    {
        Parameter[] parameters = new Parameter[]
        {
            new Parameter() { Name = "正一郎", Age = 52 },
            new Parameter() { Name = "征史郎", Age = 18 },
            new Parameter() { Name = "征史郎", Age = 18 },
        };

        IEnumerable<Parameter> parameters_D = parameters.Distinct();

        System.Console.WriteLine( "parameters         :{0}", parameters.Text() );
        System.Console.WriteLine( "parameters Distinct:{0}", parameters_D.Text() );

        System.Console.ReadKey();
    }

    public static string Text( this IEnumerable i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
}

parameters :[Name:正一郎, Age:52], [Name:征史郎, Age:18], [Name:征史郎,
Age:18],
parameters Distinct:[Name:正一郎, Age:52], [Name:征史郎, Age:18], [Name:征史郎,
Age:18],

我们会发现即使内容一样也没有去除,因为这里比较的是地址。

using System.Linq;
using System.Collections;
using System.Collections.Generic;

public static class Program
{
    private class Parameter
    {
        public string   Name    { get; set; }
        public int      Age     { get; set; }
        
        public override string ToString()
        {
            return string.Format( "Name:{0}, Age:{1}", Name, Age );
        }
    }

    static void Main( string[] args )
    {
        Parameter paramA = new Parameter() { Name = "正一郎", Age = 52 };
        Parameter paramB = new Parameter() { Name = "征史郎", Age = 18 };
        Parameter[] parameters = new Parameter[]
        {
            paramA,
            paramB,
            paramB,
        };

        IEnumerable<Parameter> parameters_D = parameters.Distinct();

        System.Console.WriteLine( "parameters         :{0}", parameters.Text() );
        System.Console.WriteLine( "parameters Distinct:{0}", parameters_D.Text() );

        System.Console.ReadKey();
    }

    public static string Text( this IEnumerable i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
}

parameters :[Name:正一郎, Age:52], [Name:征史郎, Age:18], [Name:征史郎,
Age:18],
parameters Distinct:[Name:正一郎, Age:52], [Name:征史郎, Age:18],

换成相同的元素则被成功剔除。那么我们有办法自定义比较规则吗?
答案是可以的,我们需要通过继承IEqualityComparer实现比较类。

using System.Linq;
using System.Collections;
using System.Collections.Generic;

public static class Program
{
    private class Parameter
    {
        public string   Name    { get; set; }
        public int      Age     { get; set; }
        
        public override string ToString()
        {
            return string.Format( "Name:{0}, Age:{1}", Name, Age );
        }
    }

    private class ParameterComparer : IEqualityComparer<Parameter>
    {
        public bool Equals( Parameter i_lhs, Parameter i_rhs )
        {
            if( i_lhs.Name  == i_rhs.Name &&
                i_lhs.Age   == i_rhs.Age )
            {
                return true;
            }
            return false;
        }

        public int GetHashCode( Parameter i_obj )
        {
            return i_obj.Age ^ i_obj.Name.GetHashCode();
        }
    }

    static void Main( string[] args )
    {
        Parameter[] parameters = new Parameter[]
        {
            new Parameter() { Name = "正一郎", Age = 52 },
            new Parameter() { Name = "征史郎", Age = 18 },
            new Parameter() { Name = "征史郎", Age = 18 },
        };

        ParameterComparer Comparer = new ParameterComparer();
        IEnumerable<Parameter> parameters_D = parameters.Distinct( Comparer );

        System.Console.WriteLine( "parameters         :{0}", parameters.Text() );
        System.Console.WriteLine( "parameters Distinct:{0}", parameters_D.Text() );

        System.Console.ReadKey();
    }

    public static string Text( this IEnumerable i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
}

parameters :[Name:正一郎, Age:52], [Name:征史郎, Age:18], [Name:征史郎,
Age:18],
parameters Distinct:[Name:正一郎, Age:52], [Name:征史郎, Age:18],
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我寄人间雪满头丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值