使用Union / Intersect合并复杂对象列表

时间:2013-09-28 22:25:55

标签: c# linq

考虑两个复杂对象列表:

        var first = new List<Record>
            {
                new Record(1, new List<int> { 2, 3 }),
                new Record(4, new List<int> { 5, 6 })
            };

        var second = new List<Record>
            {
                new Record(1, new List<int> { 4 })
            };

其中Record的定义如下。没什么好看的,只有一个Id的课程和列表 SecondaryIdentifiers

    public class Record
    {
        private readonly IList<int> _secondaryIdentifiers;
        private readonly int _id;

        public Record(int id, IList<int> secondaryIdentifiers)
        {
            _id = id;
            _secondaryIdentifiers = secondaryIdentifiers;
        }

        public IList<int> SecondaryIdentifiers
        {
            get { return _secondaryIdentifiers; }
        }

        public int Id
        {
            get { return _id; }
        }
    }

我如何联合/感兴趣使Union和Intersect操作合并 SecondaryIdentifier。

        var union = first.Union(second);
        var intersect = first.Intersect(second);

联盟将

            {
                new Record(1, new List<int> { 2, 3 , 4 }),
                new Record(4, new List<int> { 5, 6 })
            };

相交将是

            {
                new Record(1, new List<int> { 2, 3 , 4 }),
            };

我尝试了什么

我尝试使用first.Union(second, new EqualityComparer()) EqualityComparer扩展IEqualityComparer<Record>并合并两个SecondaryIdentifiers如果比较的两个项目相同,但对我来说似乎有些笨拙

有更优雅的方式吗?

2 个答案:

答案 0 :(得分:2)

  

有更优雅的方式吗

这是基于意见的,但我会这样做:

var union = first.Concat(second)
            .GroupBy(x => x.Id)
            .Select(g => g.SelectMany(y => y.SecondaryIdentifiers).ToList())
            .ToList();


var intersect = first.Concat(second)
                .GroupBy(x => x.Id)
                .Where(x => x.Count() > 1)
                .Select(g => g.SelectMany(y => y.SecondaryIdentifiers).ToList())
                .ToList();

PS:您可以随意删除.ToList()以进行延迟评估。

答案 1 :(得分:0)

这适用于工会部分:

from a in first
join b in second on a.Id equals b.Id into rGroup
let ids = a.SecondaryIdentifiers.Union(rGroup.SelectMany(r => r.SecondaryIdentifiers))
select new Record(a.Id, ids.ToList())

和交叉:

from a in first
join b in second on a.Id equals b.Id
select new Record(a.Id, a.SecondaryIdentifiers.Union(b.SecondaryIdentifiers).ToList())