1
나는 고전적인 중복 항목을 목록/중첩 목록 문제에서 제거해야합니다. 그러나 내가 따르려고하는 특정 규칙 때문에 해결책은 간단하지 않습니다. 원하는대로 작동하는 샘플 응용 프로그램을 작성했습니다. 그러나 그것은 clunky 보인다. 나는 더 우아함을 찾고 있으며 가능하다면 더 많은 효율성을 기대하고있다. 아마도 LINQ/확장 메서드가 도움이 될 수 있습니다. 어떤 제안?구조/목록에서 중복 항목을 제거하고 가장 좋은 것을 보관하십시오
class Program
{
static void Main(string[] args)
{
var sellers = new List<Seller>()
{
new Seller()
{
Id = 1,
Products = new List<Product>()
{
new Product() { Sku = "Alpha", Price = 5.0, Shipping = 2.0 },
new Product() { Sku = "Beta", Price = 5.0, Shipping = 2.0 }, // more expensive sku within same seller
new Product() { Sku = "Beta", Price = 4.0, Shipping = 2.0 },
new Product() { Sku = "Gamma", Price = 8.0, Shipping = 2.0 }
}
},
new Seller()
{
Id = 2,
Products = new List<Product>()
{
new Product() { Sku = "Alpha", Price = 5.0, Shipping = 1.0 },
new Product() { Sku = "Beta", Price = 5.0, Shipping = 1.0 },
new Product() { Sku = "Gamma", Price = 8.0, Shipping = 2.0 }
}
}
};
// Eliminate duplicate Products amongst all sellers that have matching "Sku".
// Rules:
// Keep the Product with the lowest price.
// If price is equal, keep the product with lower shipping.
// If shipping is also equal, then keep the product with lowest seller Id.
// If at the end of all comparisons, a seller ends up with no products, then remove that seller.
// In this example, I expect to have (not necessarily in this order):
// 1.{Beta, 4.0, 2.0} // Fred.Beta has a lower price than Bob.Beta
// 1.{Gamma, 8.0, 2.0} // Fred.Gamma is an identical deal to Bob, but Fred is first in the list
// 2.{Alpha, 5.0, 1.0} // Bob.Alpha has a lower shipping cost than Fred.Alpha
var newSellers = new List<Seller>();
foreach (var seller in sellers)
{
foreach (var product in seller.Products)
{
// TODO: Possible performance improvement? Check for existing seller & product in newSellers before calling any code below.
var bestSeller = seller;
var bestProduct = product;
FindBestSellerAndProduct(sellers, ref bestSeller, ref bestProduct);
AddIfNotExists(newSellers, bestSeller, bestProduct);
}
}
newSellers.Sort((x, y) => x.Id.CompareTo(y.Id)); // Ensures the list is sorted by seller id... do I really care?
}
private static void FindBestSellerAndProduct(IList<Seller> sellers, ref Seller seller, ref Product product)
{
string sku = product.Sku;
foreach (var s in sellers)
{
foreach (var p in s.Products.Where(x => x.Sku == sku))
{
if ((product.Price > p.Price) ||
(product.Price == p.Price && product.Shipping > p.Shipping) ||
(product.Price == p.Price && product.Shipping == p.Shipping && seller.Id > s.Id))
{
seller = s;
product = p;
}
}
}
}
private static void AddIfNotExists(IList<Seller> sellers, Seller seller, Product product)
{
var newSeller = sellers.SingleOrDefault(x => x.Id == seller.Id);
if (newSeller == null)
{
// Add input seller and product if seller doesn't already exist in our list.
newSeller = new Seller() { Id = seller.Id, Products = new List<Product>() };
newSeller.Products.Add(product);
sellers.Add(newSeller);
}
else
{
var newProduct = newSeller.Products.Find(x => x.Sku == product.Sku);
if (newProduct == null)
{
// Add input product if it doesn't already exist in our list
newSeller.Products.Add(product);
}
}
}
}
// I cannot modify the below classes.
public sealed class Seller
{
public int Id;
public List<Product> Products;
}
public sealed class Product
{
public string Sku;
public double Price;
public double Shipping;
}
매우 똑똑하고 작동합니다! 고맙습니다. 그것은 내 버전 크기의 1/3이지만 느리게 7 번 실행됩니다. 따라서 실제 프로젝트에서 실제 성능을 관찰하려면 약간의 테스트가 필요합니다. 다시 한번 감사드립니다. –