I have a list of objects in an ArrayList PList
. The object looks like this
Product
{
int ProductId,
string ProductDescription,
int StoreId
int supplierid
}
I would like to add non repeating combination of Products into another array
Product[] Parray
example:
ArrayList Plist
has :
productid , productdescription, storeid, supplierid
1, "AB", 11 , 123
2, "CD", 24 ,454
1, "AB", 11 ,431
I would like the Product[] Parray
to have
productid , productdescription, storeid, supplierid
1, "AB", 11 ,123
2, "CD", 24 , 454
I know that I can use a hashtable for key value pairs ,but in this case I have 3 keys ProductId, description & storeid
Here is my code as of now:
private Types.Product[] LoadProducts()
{
ArrayList PList = new ArrayList();
// Business Logic , extracting values from xml using xpath
//Loop though each xml node
for (int j = 0; j < xmlprodlist.Count; j++)
{
//Business logic
PList.Add(call another function here);
}
//What code here ??
Types.Product[] PArray = (Types.Product[])PArrayList.ToArray(typeof(Types.Product));
return PArray;
}
Can anyone tell me what code I need to add above in the place what code here ?
You could use a simple GroupBy
to group your data, and select the first item of each group:
Product[] Parray = PList.OfType<Product>()
.GroupBy(p => new {p.ProductId, p.ProductDescription, p.StoreId})
.Select(p => p.First())
.ToArray();
Note that you don't have a reason to use ArrayList
anymore (you even tagged your question C# 4.0), better use the generic List<T>
class, which will make your code more typesafe and more understandable.
Another way is to provide a IEqualityComparer
that compares the three properties in question to the Distinct
method:
Product[] Parray = PList.OfType<Product>()
.Distinct(theIEqualityComparer)
.ToArray();
I probably did not understand... why not an hastable int->Product (productId->Product)
something like (sorry I don't have ac# compiler here, this is just a draft)
proDictionary<int, Product> table = new Dictionary<int, Product>();
foreach (var x : inproducts)
// if (!table.Keys.Contains(x)) // if you want to keep the first
table.Add(x.ProductId, x);
return table.Values.ToArray();
From what i understand you have a list of products and you want a distict list based on the ID. First override Equals and GetHashCode in the Product class and then use LINQ to get the distict items:
public class Product
{
public int ProductId;
public string ProductDescription;
public int StoreId;
public int supplierid;
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
return false;
return ProductId == ((Product)obj).ProductId;
}
public override int GetHashCode()
{
return ProductId.GetHashCode();
}
}
And use it like this
List<Product> products = new List<Product>();
products.Add(new Product() { ProductId = 1, ProductDescription = "Product 1" });
products.Add(new Product() { ProductId = 2, ProductDescription = "Product 2" });
products.Add(new Product() { ProductId = 3, ProductDescription = "Product 3" });
products.Add(new Product() { ProductId = 1, ProductDescription = "Product 1 again" });
var distictItems = products.Distinct().ToList();
Console.WriteLine(distictItems.Count()); //This prints 3
One way to do this would be to write an implementation of IEqualityComparer. Something like:
public class ProductEqualityComparer : IEqualityComparer<Product>
{
public bool Equals(Product x, Product y)
{
return x != null && y != null &&
x.ProductId == y.ProductId &&
x.ProductDescription == y.ProductDescription &&
x.StoreId == y.StoreId;
}
public int GetHashCode(Product obj)
{
return String.Format("{0}-{1}-{2}",
obj.ProductId,
obj.ProductDescription,
obj.StoreId)
.GetHashCode();
}
}
You could then do:
var comparer = new ProductEqualityComparer();
var array = (Types.Product[])PList.ToArray(typeof(Types.Product));
var distinct = array.Distinct(comparer);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.