我有一个包含myType类型对象的列表,并且第二个列表包含相同类型的对象。此对象具有ID属性,并且第一个列表中的对象与第二个列表中的项目不同。另外我知道在两个列表中,没有两个或更多具有相同ID的对象。
我想从第一个列表中删除ID在第二个列表中的项目,然后将第二个列表的项目添加到第一个列表中。
我在想这段代码:
Dictionary<long, int> myDicIdWithPositionFirstList = new Dictionary<long, int>();
for(int i = 0; i < myFirstList.Count; i++)
{
myDicIdWithPositionFirstList.Add(myFirstList[i].ID, i);
}
foreach (MyType iterator in mySecondList)
{
int myPosition = (myDicIdWithPositionFirstList.ContainsKey(iterator.ID) ? myDicIdWithPositionFirstList[iterator.ID] : -1;
DgdOrdenesTrabajo.RemoveAt(myPosition);
MyFirstList.Add(iterator);
}
它的想法是用第一个列表的对象的ID和位置创建一个diccitionary。这具有O(n)复杂性。
稍后,我迭代第二个列表。我检查第一个列表中是否有。如果它在第一个列表中,我得到字典中的位置,即O(1),我从我知道的位置删除。
但我不知道这是不是一个好方法,或者有更好的方式,更简单,更快的性能。
感谢。
答案 0 :(得分:1)
首先,如果列表包含唯一对象(唯一ID),那么请使用意味着唯一性的集合: Set ,if (data > 100 && data <= 20000) {
otherValue = Math.ceil(data/1000)*10;
}
作为不错的选择。
如果HashSet<MyObject>
未根据MyObject
实现值相等,则使用重载创建集合,以便您定义自定义ID
。
完成后,只需迭代第2组并检查每个对象是否包含在第1组中。如果是,则从第1组中删除并将第2组中的对象添加到第1组。
答案 1 :(得分:0)
如果目标是获得两个列表的并集,那么一种方法是使用Enumerable.Union,它使用默认的相等比较器。或者您可以在第二组中过滤掉重复项,然后将该过滤后的列表添加到第一个列表中。如,
MasterList.AddRange(SecondList.Where(i => !MasterList.Any(m => m.MyId == i.MyId)));
答案 2 :(得分:0)
您的方法是O(n)
,其中n
是 MyFirstList 的大小 - 您在索引处删除元素,因此右侧部分始终被移位,因此它是{{1 }}。即使它是链表,RemoveAt也需要O(n)
次。总的来说,您的实施是O(n)
而不是天真的O(m*n)
更好的方法是不使用列表 - 使用二叉树,将 ID 作为键。因此,您的结构将存储在 SortedDictionary 中,而不是 List 和
单个项目的删除/更新/创建将采用O(m*(n+1))
,两个集合同步将采用O(log(n))
:
O(m*log(n))
<强> PS 强>
您实际上不需要显式删除,因为您添加了新元素作为替换。因此,您只需更新指定索引处的值,而不是删除它,否则添加:
var myFirstDictionary = new SortedDictionary(myFirstList.Count);
foreach(var item in myFirstList)
{
myFirstDictionary[item.Id] = item;
}
//updating/creating values in first list by using second list values
foreach(var item in mySecondList)
{
myFirstDictionary[item.Id] = item;
}
答案 3 :(得分:0)
尝试下面的内容,列出第一个列表中未包含的所有项目
var result = DgdOrdenesTrabajo.FindAll(v => !mySecondList.FindAll(var=>myFirstList.Any(var1=>(var1.ID==var.ID)))
.Any(v2=>v2.ID==v.ID)).ToList<MyType>();
答案 4 :(得分:0)
我想从第一个列表中删除ID在第二个列表中的项目,然后将第二个列表的项目添加到第一个列表中。
void Main()
{
var first = new []
{
new MyType{Id = 11, Name = "John"},
new MyType{Id = 12, Name = "Jack"},
new MyType{Id = 13, Name = "Jim"},
new MyType{Id = 14, Name = "Joel"},
new MyType{Id = 15, Name = "Jay"},
};
var second = new[]
{
new MyType{Id = 21, Name = "Jake"},
new MyType{Id = 22, Name = "Jan"},
new MyType{Id = 13, Name = "Jim"},
new MyType{Id = 14, Name = "Joel"},
new MyType{Id = 23, Name = "Jane"},
new MyType{Id = 24, Name = "Jade"},
};
var results = first
.Union(second)
.Distinct(new MyTypeComparer());
results.Dump();
//11 John
//12 Jack
//13 Jim
//14 Joel
//15 Jay
//21 Jake
//22 Jan
//23 Jane
//24 Jade
}
public class MyType
{
public int Id { get; set; }
public string Name { get; set; }
}
public class MyTypeComparer : IEqualityComparer<MyType>
{
public bool Equals(MyType x, MyType y)
{
return x.Id == y.Id;
}
public int GetHashCode(MyType obj)
{
return obj.Id ^ 13;
}
}