繁体   English   中英

在C#中合并两个列表

[英]Merge two lists in C#

我想将具有不同属性的两个列表合并到一个列表中,但是在合并它时,我想检查在这个特定示例中是否存在两个列表中的确切日期,如果有,我想要同时使用两个列表来自该元素的属性,并将它们合并到另一个列表中的一个元素中

清单1:

List<object> r1 = (from x in sp1 select new 
                   { 
                     x.Imported, 
                     x.Period 
                   }).ToList<object>();

L1结果:

在此输入图像描述

清单2:

List<object> r2 = (from x in sp2 select new 
                   { 
                     x.Dissolution, 
                     x.Period 
                   }).ToList<object>();

L2结果:

在此输入图像描述


通缉结果:

在此输入图像描述

现在,这就是我如何合并r1和r2:

 List<object> r3 = new List<object>(r1.Concat(r2));

您可以将它们转换为相同的类型并使用这样的东西

r1
.Select(x => new { Imported = x.Imported, Dissolution = null, Period = x.Period)
.Concat(
    r2.Select(x => new { Imported = null, Dissolution = x.Dissolution, Period = x.Period))
.GroupBy(x => x.Period)
.Select(x => new { Imported = x.Max(e => e.Imported),
                   Dissolution = x.Max(e => e.Dissolution),
                   Period = x.Key);

创建一个字典

Dictionary MyDict<String, List<Object>>;

MyDict[object.Perdiod].Add(object);

对于每个日期,字典中都会有一个条目,它将在此“日期索引”中保留该时间段内发生的所有对象的列表。

最简单的IMO方式,它不需要对每个添加的条目进行O(n)检查

只需确保在添加数据时它不是IE IE

MyDict[Object.Period] != null

另外,Nikhil Agrawal表示我不会使用Object来保存一个列表...它感觉不对并且容易出错。 您可能希望声明一个将像Interface一样使用的抽象类,或者只是声明这些项(对象)的接口。

AFAK你需要反思来实现这一点,因为在编译时分配匿名类型的名称这里是一个如何实现你想要的例子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;   
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<ImportedType> sp1 = new List<ImportedType>();
            List<DissolutionType> sp2 = new List<DissolutionType>();
            sp1.AddRange( new ImportedType[]{new ImportedType() { Imported = 2, Period = "2024-02" }, new ImportedType() { Imported = 2, Period = "2014-11" }, new ImportedType() { Imported = 2, Period = "2024-12" }});
            sp2.AddRange(new DissolutionType[] { new DissolutionType() { Dissolution = 2, Period = "2024-02" }, new DissolutionType() { Dissolution = 2, Period = "2034-02" }, new DissolutionType() { Dissolution = 2, Period = "2024-12" } });    
            var  r1 = (from x in sp1
                               select new
                               {
                                   x.Imported,
                                   x.Period
                               }).ToList<object>();
            var r2 = (from x in sp2
                               select new
                               {
                                   x.Dissolution,
                                   x.Period
                               }).ToList<object>();                
            var r3 = r1.Concat(r2).Except(r1.Where(res =>
                {    
                    object vp2 = r2.SingleOrDefault(res2 => GetValue(res2) == GetValue(res));
                    if (vp2!=null)
                    {
                        return true; 
                    }    
                    return false;
                }));        
        }

        private static object GetValue(object res)
        {
            Type t = res.GetType();
            PropertyInfo p = t.GetProperty("Period");
            object v = p.GetValue(res, null);
            return v; 
        }
    }
}

//这里我想你实现了这样的2个类

public class ImportedType
    {
        public int Imported { get; set;  }
        public string Period { get; set; }

    }
    public class DissolutionType
    {
        public int Dissolution { get; set; }
        public string  Period { get; set; }

    }

结果 在此输入图像描述

我同意Nikhil Agrawal的观点,因为代码现在确实需要修复,因为使用匿名类型真的很难,特别是因为它们已被强制转换为对象。

忽略它,并接受它作为挑战(使用匿名类型强制转换为对象),这就是我提出的:

合并的代码执行完整的外部联接:

        Func<object, object> getPeriodKey = first =>
        {
            var periodProperty = first.GetType().GetProperty("Period");
            return periodProperty.GetValue(first);
        };

        var temp = r1.GroupJoin(r2, getPeriodKey, getPeriodKey, (obj, tInner) =>
        {
            dynamic right = tInner.FirstOrDefault();

            if (right == null)
                return (object)(new
                {
                    Period = ((dynamic)obj).Period,
                    Imported = ((dynamic)obj).Imported,
                });
            else
                return (object)(new
                {
                    Period = ((dynamic)obj).Period,
                    Imported = ((dynamic)obj).Imported,
                    Dissolution = (int?)right.Dissolution,
                });

        });

        var merged = temp.Union(r2, new RComparer());

并且所需的比较器如下:

    class RComparer : IEqualityComparer<object>
    {
        public bool Equals(object x, object y)
        {
            var xPeriodProperty = x.GetType().GetProperty("Period");
            var yPeriodProperty = y.GetType().GetProperty("Period");

            if (xPeriodProperty != null && yPeriodProperty != null)
            {
                var xPeriod = (string)xPeriodProperty.GetValue(x);
                var yPeriod = (string)yPeriodProperty.GetValue(y);
                return xPeriod == yPeriod;
            }
            else
                return base.Equals(y);
        }

        public int GetHashCode(object obj)
        {
            var periodProperty = obj.GetType().GetProperty("Period");

            if (periodProperty != null)
                //This will essentially hash the string value of the Period
                return periodProperty.GetValue(obj).GetHashCode();
            else
                return obj.GetHashCode();
            ;
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM