将现有列表与“更新”列表合并
本文关键字:列表 更新 合并 | 更新日期: 2023-09-27 18:30:56
我有两个列表:1) 现有列表2) 更新列表
两个列表都包含以下一类
public class Subcategory
{
public int category_id { get; set; }
public List<ProductInfo> products { get; set; }
public List<Subcategory> subcategories { get; set; }
}
列表 1:
Subcat1
- Id: 1
- products:
{product 1}
{product 2}
- subcategories:
{subcat2
- Id: 2
- products:
{product 3}
- subcategories:
{subcat3
- Id: 2
- products:
{product 4}
- subcategories:
{subcat4}
}
列表 2 是一个更新列表,它包含新的类别和产品
Subcat1
- Id: 1
- products:
{product 5}
- subcategories:
{subcat2
- Id: 2
- products:
{product 6}
- subcategories:
{subcat5
- Id: 5
- products:
{product 7}
}
那么应该发生什么:- 将产品 5 添加到子类别 1- 将产品 6 添加到子类别 1- 将子猫5添加到子猫2的类别列表中
我想出了如何更新现有项目并删除删除项目。我有一个 int 列表,其中包含所有类别和所有产品之一的 id,如果当前产品或类别不在各自的列表中,则会将其删除。递归地,我还生成了一个列表,其中包含所有类别和可以在 List2 中找到的所有产品,称为 generated 类别 和 generated Products。然后,使用以下代码适用于此更新和删除行为:
private List<Product.Subcategory> UpdateObjects(List<Product.Subcategory> prod)
{
try
{
int catcount = prod.Count;
if (catcount > 0)
{
for (int i = catcount - 1; i > -1; i--)
{
try
{
//Check if exists
if (categories.All(u => u.id != prod[i].category_id))
{
prod.RemoveAt(i);
}
}
catch (Exception)
{
//throw;
}
foreach (var newsubCat in generatedSubcategories)
{
if (prod[i].category_id == newsubCat.category_id)
{
prod[i].delivery_time = newsubCat.delivery_time;
prod[i].image = newsubCat.image;
prod[i].name = newsubCat.name;
prod[i].pickup_time = newsubCat.delivery_time;
prod[i].sequence = newsubCat.sequence;
prod[i].translation_missing = newsubCat.translation_missing;
prod[i].use_firm_time_settings = newsubCat.use_firm_time_settings;
}
}
if (prod[i].products != null)
{
foreach (var oldProduct in prod[i].products)
{
int count = generatedProducts.Count;
if (count != 0)
{
for (int z = count - 1; i > -1; i--)
{
try
{
//Check if exists
if (products.All(u => u.id != generatedProducts[z].id))
{
generatedProducts.RemoveAt(z);
}
else
{
if (oldProduct.id == generatedProducts[z].id)
{
oldProduct.amount = generatedProducts[z].amount;
oldProduct.comment = generatedProducts[z].comment;
oldProduct.delivery_time = generatedProducts[z].delivery_time;
oldProduct.description = generatedProducts[z].description;
oldProduct.image = generatedProducts[z].image;
oldProduct.ingredients = generatedProducts[z].ingredients;
oldProduct.name = generatedProducts[z].name;
oldProduct.pickup_time = generatedProducts[z].pickup_time;
oldProduct.price = generatedProducts[z].price;
oldProduct.sequence = generatedProducts[z].sequence;
oldProduct.times = generatedProducts[z].times;
oldProduct.translation_missing = generatedProducts[z].translation_missing;
oldProduct.unit = generatedProducts[z].unit;
oldProduct.use_category_time_settings = generatedProducts[z].use_category_time_settings;
}
}
}
catch (Exception)
{
//throw;
}
}
}
}
if (prod[i].subcategories != null)
{
GenerateCategoryList(prod[i].subcategories);
}
}
}
}
}
catch (Exception)
{
//throw;
}
return prod;
}
我将如何在指定位置添加新类别和产品?
好的,多亏了 Piyush 的提示,我想出了一个粗略的方法(非常需要优化,但通常有效):
1)将原始列表存储在变量中(oldList是从不同的类传递的)
Subcategory OriginalList = new Subcategory();
OriginalList = oldList;
2) 生成包含所有待更新类别和产品的字典"prod"是基础树,您将递归地浏览它。
我在名为 parent_category_id 的 Subcategory 类中添加了一个额外的字段,该字段显然存储父 id,每次迭代都将其传递给函数。生成产品和生成的子类别是以后更新现有项目所必需的。
List<Product.ProductInfo> generatedProducts = new List<Product.ProductInfo>();
List<Product.Subcategory> generatedSubcategories = new List<Product.Subcategory>();
Dictionary<int, List<Product.Subcategory>> dicCategories = new Dictionary<int, List<Product.Subcategory>>();
Dictionary<int, List<Product.ProductInfo>> dicProducts = new Dictionary<int, List<Product.ProductInfo>>();
private List<Product.Subcategory> GenerateProductList(List<Product.Subcategory> prod, int parentCategoryId)
{
foreach (var subcategory in prod)
{
generatedSubcategories.Add(subcategory);
if (dicCategories.ContainsKey(subcategory.category_id))
{
//Add to value
subcategory.parent_category_id = parentCategoryId;
dicCategories[subcategory.category_id].Add(subcategory);
}
else
{
subcategory.parent_category_id = parentCategoryId;
dicCategories.Add(subcategory.category_id, new List<Product.Subcategory> { subcategory });
}
if (subcategory.products != null)
{
foreach (var product in subcategory.products)
{
generatedProducts.Add(product);
if (dicProducts.ContainsKey(subcategory.category_id))
{
//Add to value
dicProducts[subcategory.category_id].Add(product);
}
else
{
dicProducts.Add(subcategory.category_id, new List<Product.ProductInfo>{ product });
}
}
}
if (subcategory.subcategories != null)
{
GenerateProductList(subcategory.subcategories, subcategory.category_id);
}
}
return prod;
}
3)调用GenerateProductList用新数据填充列表,使用父ID 0表示它是根。
GenerateProductList(yourNewDataList, 0);
4)好的,现在是时候创建一个将新项目和旧项目组合在一起的列表了。
Product NewList = new Product();
private void AddNewItems()
{
NewList.data = new List<Product.Subcategory>();
foreach (var subcat in OriginalList.data)
{
if (!NewList.data.Any(c => c.category_id == subcat.category_id))
{
NewList.data.Add(subcat);
}
}
Product tempList = Product.DeepCopy(NewList);
foreach (var cat in dicCategories)
{
foreach (var toAdd in cat.Value)
{
if (toAdd.parent_category_id == 0)
{
//Root
if (!NewList.data.Any(c => c.category_id == toAdd.category_id))
{
tempList.data.Add(toAdd);
}
}
else
{
foreach (var subcat in OriginalList.data)
{
Product.Subcategory y = Product.FindSubCat(subcat, toAdd.parent_category_id);
if (y != null)
{
Product.Subcategory x = BrowseCategories(subcat, toAdd);
int index = NewList.data.IndexOf(subcat);
tempList.data[index] = x;
}
}
}
}
}
NewList = tempList;
foreach (var product in dicProducts)
{
foreach (var subcat in NewList.data)
{
foreach (var subproduct in product.Value)
{
Product.Subcategory y = Product.FindSubCat(subcat, product.Key);
if (y != null)
{
Product.Subcategory x = BrowseProducts(subcat, subproduct, product.Key);
int index = NewList.data.IndexOf(subcat);
tempList.data[index] = x;
x = x;
}
//tempList.data[subcat] =
}
}
}
NewList = tempList;
}
private Product.Subcategory BrowseProducts(Product.Subcategory category, Product.ProductInfo toAdd, int catId)
{
try
{
if (category.category_id == catId)
{
if (category.products == null) category.products = new List<Product.ProductInfo>();
var remove = category.products.SingleOrDefault(s => s.id == toAdd.id);
if (remove != null)
{
if (remove.id != 0)
{
category.products.Remove(remove);
}
}
category.products.Add(toAdd);
return category;
}
if (category.products == null) return category;
if (category.subcategories == null) return category;
foreach (var cat in category.subcategories)
{
if (cat.category_id == catId)
{
if (cat.products == null) cat.products = new List<Product.ProductInfo>();
var remove = cat.products.SingleOrDefault(s => s.id == toAdd.id);
if (remove != null)
{
if (remove.id != 0)
{
cat.products.Remove(remove);
}
}
cat.products.Add(toAdd);
return category;
}
BrowseProducts(cat, toAdd, catId);
}
return category;
}
catch (Exception)
{
throw;
}
}
private Product.Subcategory BrowseCategories(Product.Subcategory category, Product.Subcategory toAdd)
{
try
{
if (category.category_id == toAdd.parent_category_id)
{
if (category.subcategories == null) category.subcategories = new List<Product.Subcategory>();
var remove = category.subcategories.SingleOrDefault(s => s.category_id == toAdd.category_id);
if (remove != null)
{
if (remove.category_id != 0)
{
category.subcategories.Remove(remove);
}
}
category.subcategories.Add(toAdd);
return category;
}
if (category.subcategories == null) return category;
foreach (var cat in category.subcategories)
{
if (cat.category_id == toAdd.parent_category_id)
{
if (cat.subcategories == null) cat.subcategories = new List<Product.Subcategory>();
var remove = cat.subcategories.SingleOrDefault(s => s.category_id == toAdd.category_id);
if (remove != null)
{
if (remove.category_id != 0)
{
cat.subcategories.Remove(remove);
}
}
cat.subcategories.Add(toAdd);
return category;
}
BrowseCategories(cat, toAdd);
}
return category;
}
catch (Exception)
{
throw;
}
}
5)太好了!NewList 现在包含所有旧数据和新数据,但我们仍然需要更新旧数据。
private List<Product.Subcategory> UpdateObjects(List<Product.Subcategory> prod)
{
try
{
int catcount = prod.Count;
if (catcount > 0)
{
for (int i = catcount - 1; i > -1; i--)
{
//if (prod[i].category_id == 203)
//{
// Debug.WriteLine("");
//}
try
{
//Check if exists
if (categories.All(u => u.id != prod[i].category_id))
{
//if (prod[i].category_id == 203)
//{
// prod.RemoveAt(i);
//}
if (!dicCategories.ContainsKey(prod[i].category_id))
{
prod.RemoveAt(i);
}
}
}
catch (Exception)
{
//throw;
}
foreach (var newsubCat in generatedSubcategories)
{
if (prod[i].category_id == newsubCat.category_id)
{
prod[i].delivery_time = newsubCat.delivery_time;
prod[i].image = newsubCat.image;
prod[i].name = newsubCat.name;
prod[i].pickup_time = newsubCat.delivery_time;
prod[i].sequence = newsubCat.sequence;
prod[i].translation_missing = newsubCat.translation_missing;
prod[i].use_firm_time_settings = newsubCat.use_firm_time_settings;
}
}
if (prod[i].products != null)
{
foreach (var oldProduct in prod[i].products)
{
int count = generatedProducts.Count;
if (count != 0)
{
for (int z = count - 1; i > -1; i--)
{
try
{
//Check if exists
if (products.All(u => u.id != generatedProducts[z].id))
{
generatedProducts.RemoveAt(z);
}
else
{
if (oldProduct.id == generatedProducts[z].id)
{
oldProduct.amount = generatedProducts[z].amount;
oldProduct.comment = generatedProducts[z].comment;
oldProduct.delivery_time = generatedProducts[z].delivery_time;
oldProduct.description = generatedProducts[z].description;
oldProduct.image = generatedProducts[z].image;
oldProduct.ingredients = generatedProducts[z].ingredients;
oldProduct.name = generatedProducts[z].name;
oldProduct.pickup_time = generatedProducts[z].pickup_time;
oldProduct.price = generatedProducts[z].price;
oldProduct.sequence = generatedProducts[z].sequence;
oldProduct.times = generatedProducts[z].times;
oldProduct.translation_missing = generatedProducts[z].translation_missing;
oldProduct.unit = generatedProducts[z].unit;
oldProduct.use_category_time_settings = generatedProducts[z].use_category_time_settings;
}
}
}
catch (Exception)
{
//throw;
}
}
}
}
if (prod[i].subcategories != null)
{
UpdateObjects(prod[i].subcategories);
}
}
}
}
}
catch (Exception)
{
//throw;
}
return prod;
}
调用函数:
List<Product.Subcategory> completedList = UpdateObjects(addedList.data);
现在完成列表包含所有新的,旧的和更新的项目!
仍然欢迎有关改进这一点的建议。