我有两个带有类的列表
public class Product
{
int id;
string url;
ect.
}
我需要在旧列表(10k +元素)中按ID比较新列表(10个元素) 如果id相同,则只需将新列表中的数据替换为旧列表
我认为使用LINQ会很好。 你能帮帮我怎样才能使用LINQ或者有击球手库?
答案 0 :(得分:1)
您是否需要修改集合或返回新集合?
如果您要返回新的收藏品,可以
var query = from x in oldItems
join y in newItems on y.Id equals x.Id into g
from z in g.DefaultIfEmpty()
select z ?? x;
var new List = query.ToList();
此方法将忽略newItems中旧项目中不存在的条目。
如果您要修改集合,最好使用字典并在任何地方引用它。
您可以通过
从列表中创建字典var collection = items.ToDictionary(x => x.Id, x => x);
注意修改字典不会改变源集合,我们的想法是用字典对象替换你的集合。
如果您正在使用字典,则可以迭代新集合并检查密钥。
foreach (var item in newItems.Where(x => collection.ContainsKey(x.Id))) {
collection[item.Id] = item;
}
字典是可迭代的,因此您可以根据需要循环遍历Values集合。添加和删除很快,因为您可以通过键引用。我能想到的唯一问题是你是否依赖于集合的排序。
如果您需要使用原始集合类型,则可以在newItems集合上使用ToDictionary消息。这使您的更新代码看起来像这样。
var converted = newItems.ToDictionary(x => x.Id, x => x);
for (var i = 0; i < oldItems.Count(); i++) {
if (converted.ContainsKey(oldItems[i].Id)) {
oldItems[i] = converted[oldItems[i].Id];
}
}
这样做的好处是你只需要循环一次newitems集合,然后再进行密钥查找,因此它的cpu密集度较低。缺点是你已经为newitems创建了一个新的密钥集合,因此它消耗了更多的内存。
答案 1 :(得分:0)
向您发送一个示例函数,该函数通过两个列表的id属性连接两个列表,然后使用较新的列表更新原始Product.url
void ChangeItems(IList<Product> original, IList<Product> newer){
original.Join(newer, o => o.id, n => n.id, (o, n) => new { original = o, newer = n })
.ToList()
.ForEach(j => j.original.Url = j.newer.Url);
}
答案 2 :(得分:0)
解决方案: - :您正在寻找的LINQ
解决方案将是这样的
oldList = oldList.Select(ele => { return (newList.Any(i => i.id == ele.id) ? newList.FirstOrDefault(newObj => newObj.id == ele.id) : ele); }).ToList();
注意: - 我们在此处根据OldList
创建NewList
&amp; OldList
,即我们正在用NewList object
替换OldList object
。如果您只想要一些新的List属性,可以在类中创建一个复制方法
复制构造函数的EG
oldList = oldList.Select(ele => { return (newList.Any(i => i.id == ele.id) ? ele.Copy(newList.FirstOrDefault(newObj => newObj.id == ele.id)) : ele); }).ToList();
//Changes in your class
public void Copy(Product prod)
{
//use req. property of prod. to be replaced the old class
this.id = prod.id;
}
<强> 读 强>
即使使用linq迭代超过10k +元素也不是一个好主意,因为它仍会影响你的
CPU performance
*
答案 3 :(得分:0)
你上课了
public class Product
{
public int id;
public string url;
public string otherData;
public Product(int id, string url, string otherData)
{
this.id = id;
this.url = url;
this.otherData = otherData;
}
public Product ChangeProp(Product newProd)
{
this.url = newProd.url;
this.otherData = newProd.otherData;
return this;
}
}
注意,现在我们在数据类中有ChangeProp
方法,此方法将接受新类并使用新类的属性修改旧类并返回修改后的新类(如您所愿)你的旧类被替换为新的类属性(数据)。所以最后Linq
将是可读和干净的。
你已经有oldList
有很多条目,如果id相同,必须用newList的数据替换oldList的数据,你可以像下面这样做。
假设他们有以下数据,
List<Product> oldList = new List<Product>();
for (int i = 0; i < 10000; i++)
{
oldList.Add(new Product(i, "OldData" + i.ToString(), "OldData" + i.ToString() + "-other"));
}
List<Product> newList = new List<Product>();
for (int i = 0; i < 5; i++)
{
newList.Add(new Product(i, "NewData" + i.ToString(), "NewData" + i.ToString() + "-other"));
}
此Linq
将完成您的工作。
oldList.Where(x => newList.Any(y => y.id == x.id))
.Select(z => oldList[oldList.IndexOf(z)].ChangeProp(newList.Where(a => a.id == z.id).FirstOrDefault())).ToList();
答案 4 :(得分:0)
foreach(var product in newList)
{
int index = oldList.FindIndex(x => x.id == product.id);
if (index != -1)
{
oldList[index].url = product.url;
}
}
这将有效,我认为它也是一个更好的解决方案。 以上所有解决方案都是在内存中创建新对象并使用10k +创建新列表 记录绝对是个坏主意。 请在产品中填写字段,因为它无法访问。