忽略订单从父列表中删除重复的子列表

时间:2014-02-24 11:39:23

标签: c# linq

我的结构类似于

Parent List {ChildList1, ChildList2, ChildList3, ChildList4}
ChildList1: { "B1", "B2", "B3" }
ChildList2: { "B1", "B3", "B2" }
ChildList3: { "B1", "B2" }
ChildList4: { "B5", "B3", "B2", "B4" }

现在我想删除具有相似(相等)值的子列表,并在父列表中只保留它们的一个副本。

New Parent List {ChildList1, ChildList3, ChildList4}

我更喜欢使用Distinct,我想知道我是否可以将它用于List<>太?

List<List<string>> ParentList = new List<List<string>>();


List<string> ChildList1 = new List<string> { "B1", "B2", "B3" };
List<string> ChildList2 = new List<string> { "B1", "B3", "B2" };
List<string> ChildList3 = new List<string> { "B1", "B2" };
List<string> ChildList4 = new List<string> { "B5", "B3", "B2", "B4" };

ParentList.Add(ChildList1);
ParentList.Add(ChildList2);
ParentList.Add(ChildList3);
ParentList.Add(ChildList4);


var NewParentList = ParentList.Distinct();
// Display results.

ChildList1ChildList2被认为是平等的,只需要保留一个。所以顺序并不重要。

2 个答案:

答案 0 :(得分:1)

也许这可能会有所帮助:

class Program
{
    static void Main(string[] args)
    {
        List<List<string>> ParentList = new List<List<string>>();


        List<string> ChildList1 = new List<string> { "B1", "B2", "B3" };
        List<string> ChildList2 = new List<string> { "B1", "B3", "B2" };
        List<string> ChildList3 = new List<string> { "B1", "B2" };
        List<string> ChildList4 = new List<string> { "B5", "B3", "B2", "B4" };

        ParentList.Add(ChildList1);
        ParentList.Add(ChildList2);
        ParentList.Add(ChildList3);
        ParentList.Add(ChildList4);

        var result = ParentList.Distinct(new Comparer()).ToList();
    }
}

internal class Comparer : IEqualityComparer<List<string>>
{
    public bool Equals(List<string> list1, List<string> list2)
    {
        return list1.All(x => list2.Contains(x)) && list2.All(x => list1.Contains(x));
    }

    public int GetHashCode(List<string> obj)
    {
        return obj.Count;
    }
}

当然,您必须使用更好的算法来生成哈希码。它将删除childList1或childList2,但不保证删除哪一个。

答案 1 :(得分:1)

如果您想使用Distinct,您可以根据忽略订单的字符串实现自定义IEqualityComparer<IEnumerable<T>>来查找重复项,例如:

public class IgnoreSequenceOrderComparer<T> : IEqualityComparer<IEnumerable<T>>
{
    public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
    {
        if (x == null || y == null)
            return false;
        if (object.ReferenceEquals(x, y))
            return true;
        return x.OrderBy(str => str).OrderBy(str => str)
            .SequenceEqual(y.OrderBy(str => str).OrderBy(str => str));
    }

    public int GetHashCode(IEnumerable<T> seq)
    {
        if (seq == null) return int.MinValue;
        int hash = 0;
        unchecked
        {
            var strings = seq.OrderBy(str => str);
            foreach (T obj in strings)
                hash = 17 * hash + obj.GetHashCode();
        }
        return hash;
    }
}

现在这段代码删除了重复项:

var NewParentList = ParentList.Distinct(new IgnoreSequenceOrderComparer<string>());