[英]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.