C # Список слияния без повторения - PullRequest
2 голосов
/ 15 июля 2011

Мой вопрос находится в конце следующего кода в комментариях:

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


namespace ConsoleApplication1
{
class MyObj
{
    int m_id;

    public MyObj(int id)
    {
        this.m_id = id;
    }

    public int GetId()
    {
        return this.m_id;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var m0 = new MyObj(0);
        var m1 = new MyObj(1);
        var m2 = new MyObj(2);
        var m3 = new MyObj(3);
        var m4 = new MyObj(4);


        List<MyObj> refList1 = new List<MyObj>()
            {
                m0, m1, m2, m3
            };

        List<MyObj> refList2 = new List<MyObj>()
            {
                m1, m2, m3, m4
            };


        //How to merge refList2 into refList1 without id repeating,
        //so refList1 must be [m0, m1, m2, m3, m4]
    }
}
}

Ответы [ 4 ]

3 голосов
/ 15 июля 2011

Это можно сделать с помощью LINQ:

var resultList = refList1.Union(refList2).ToList();

Однако для этого требуется, чтобы MyObj реализовывал IEquatable<MyObj>, или использовалась другая перегрузка Union, которая занимает IEqualityComparer<T> параметр.

Для первого решения потребуется это изменение:

class MyObj : IEquatable<MyObj>
{
    int m_id;

    public MyObj(int id)
    {
        this.m_id = id;
    }

    public int GetId()
    {
        return this.m_id;
    }

    public bool Equals(MyObj other)
    {
        if (ReferenceEquals(null, other)) {
            return false;
        }
        if (ReferenceEquals(this, other)) {
            return true;
        }
        return other.m_id == this.m_id;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) {
            return false;
        }
        if (ReferenceEquals(this, obj)) {
            return true;
        }
        if (obj.GetType() != typeof(MyObj)) {
            return false;
        }
        return Equals((MyObj)obj);
    }

    public override int GetHashCode()
    {
        return this.m_id;
    }
}

Второе решение будет выглядеть следующим образом:

class MyComparer : IEqualityComparer<MyObj>
{
    public bool Equals(MyObj x, MyObj y)
    {
        return x.GetId() == y.GetId();
    }

    public int GetHashCode(MyObj obj)
    {
        return obj.GetId();
    }
}

var resultList = refList1.Union(refList2, new MyComparer()).ToList();

и не потребует изменений в class MyObj.

1 голос
/ 15 июля 2011

Вы можете использовать Union

Посмотрите здесь .

1 голос
/ 15 июля 2011

Используйте метод Union Extension .

var merged = refList2.Union(refList1).ToList();

И определить методы Equals / Hashcode. После этого он автоматически удалит дубликаты.

class MyObj{
     /*your stuff*/

     public override bool Equals(object obj)
     {        
        var r_list= obj as MyObj;
        if(r_list == null) return false;
        return this._m_id==r_list.m_id;
     }

     public override int GetHashCode()
     {
        return m_id;
     }
}
0 голосов
/ 15 июля 2011
refList1 = refList1.Union(refList2).Distinct.ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...