我想将具有不同属性的两个列表合并到一个列表中,但在合并它时,我想检查在这个特定示例中是否存在两个列表中的确切日期,如果有,我想要从这些元素中获取两个属性,并将它们合并到另一个列表中的一个元素中
列表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));
答案 0 :(得分:2)
你可以将它们转换成相同的类型并使用这样的东西
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);
答案 1 :(得分:0)
创建词典
Dictionary MyDict<String, List<Object>>;
MyDict[object.Perdiod].Add(object);
对于每个日期,在字典中都会有一个条目,它将在此日期索引&#34;保留那段时间内发生的所有对象的列表。
最简单的IMO方式,它不需要对每个添加的条目进行O(n)检查
只需确保添加数据时它不是IE IE
MyDict[Object.Period] != null
另外,Nikhil Agrawal表示我不会使用Object来保存事物列表......感觉不对并且容易出错。您可能希望声明一个将像Interface一样使用的抽象类,或者只是声明这些项(对象)的接口。
答案 2 :(得分:0)
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;
}
}
}
//这里我假设你实现了两个这样的类
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; }
}
<强>结果强>
答案 3 :(得分:0)
我同意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();
;
}
}