Reputation: 5001
Calculate the final price of each product within a List<T>
of C#.
I need to calculate price * quantity
of a simple product and return the result to the view.
Look this syntax:
var productPrice = productsPrices.Find(x => x.productId == 1);
productPrice.finalProductPrice =
(productPrice.promotionalProductPrice != 0 ?
productPrice.promotionalProductPrice :
productPrice.originalProductPrice)
* sessionProducts.Find(x => x.id == 1).quantity;
Just before of code fragment passed above, there is a string that stores the ids of the products, see:
string ids = string.Join(", ", sessionProducts.Select(x => x.id));
And I think that I need it to set a value to finalProductPrice
of each product of my productsPrices
list, but I don't know how I can perform this.
I had thought that I could use something like this:
productsPrices.Find(x => x.productId == productsPrices.Contains(ids))
.finalProductPrice =
(productsPrices.Find(x => productsPrices.Contains(ids))
.promotionalProductPrice != 0 ?
productsPrices.Find(x => productsPrices.Contains(ids))
.promotionalProductPrice :
productsPrices.Find(x => productsPrices.Contains(ids))
.originalProductPrice) *
sessionProducts.Find(x => x.id == 1).quantity;
But, of course, no success — .Contains()
doesn't work with strings.
How can I define the right finalProductPrice
for each product that my productsPrices
list has? How can I pass each id within string ids [...]
to x.productId == something
?
Hints will be welcome (E.g. don't use .Find()
, use .Select()
instead!)
Follow my ActionResult
that sends all the necessary information to my view:
Compare.cs:
public ActionResult Compare()
{
List<getMarkets_Result> markets = Markets.Build();
SessionStore sessionStore = new SessionStore();
List<getSpecificProductToShoppingList_Result> sessionProducts =
sessionStore.Get("ProductsSummary", "generic");
string ids = string.Join(", ", sessionProducts.Select(x => x.id));
List<getProductsPrices_Result> productsPrices = Products.PricesList(ids);
ListComparisonViewModel listComparisonViewModel =
new ListComparisonViewModel
{
Markets = markets,
SessionProducts = sessionStore.Get("ProductsSummary", "generic"),
ProductsPrices = productsPrices
};
return View(listComparisonViewModel);
}
If necessary, the context of my productsPrice
list:
public partial class getProductsPrices_Result
{
public decimal originalProductPrice { get; set; }
public decimal promotionalProductPrice { get; set; }
public decimal finalProductPrice { get; set; }
public string productName { get; set; }
public string marketName { get; set; }
public int productId { get; set; }
public int marketId { get; set; }
}
And I made a model called Products(.cs) to perform the logic behind of the products. The first (and single) method that this model has is CalculateFinalPrice()
:
public decimal CalculateProductPriceByQuantity(decimal price, int quantity)
{
return price * quantity;
}
Upvotes: 5
Views: 7544
Reputation: 6294
I think you should conciser creating a model that represents your data in a way that will make your business problem easier to solve. In other words, make the code work to solve you solution.
Firstly the product should not know about the quantity. Assuming this works like a cart, the product should only know about itself. So the implementation of finalProductPrice
should be much easier:
public decimal finalProductPrice
{
get
{
return (promotionalProductPrice != 0 ?
promotionalProductPrice :
originalProductPrice);
}
}
When working with your products, create a class and contain them in that to calculate the quality and total price:
public class ProductCollection
{
public IEnumerable<getProductsPrices_Result> Products { get; set; }
public int Quantity { get { return Products.Count; } }
public decimal TotalPrice
{
get
{
return Products.Sum(p => p.finalProductPrice );
}
}
public ProductCollection(IEnumerable<getProductsPrices_Result> products)
{
this.Products = products;
}
}
Now your viewmodel can look something like this:
ListComparisonViewModel
{
Markets = markets,
Products = new ProductCollection(sessionStore.Get("ProductsSummary", "generic"))
};
One important note I would like to make here is this helps to reduce your session access surface area. Session can be "accessed by anyone" and thus can become discombobulated and cause lots of issues down the road. In almost all scenarios fewer hands in the session cookie jar the better. (fewer keys as well as fewer class types and instances)
Upvotes: 1
Reputation: 2156
With what I have at hand:
foreach(var product in sessionProducts){
var productPrice == productPrices.FirstOrDefault(p=>p.ProductId == product.id);
var price = 0;
if (productPrice != null)
price = productPrice.promotionalPrice == 0 ? productPrice.originalPrice : productPrice.promotionalPrice;
product.finalPrice = product.Qty * price;
}
Upvotes: 0
Reputation: 3294
question is a bit fuzzy but looks like you may be looking for something like following
var res = (from p in products
from s in sessionproducts
where p.id == s.id
select new Product() { id = p.id, finalprice = s.qty * (p.promoprice > 0 ? p.promoprice : p.price) })
.ToList();
Upvotes: 0
Reputation: 34349
You've got a lot of issues here. Firstly, your properties should be PascalCase, not camelCase. Secondly, your class is poorly named. getProductsPrices_Result
shouldn't be prefixed with a verb, and it should be PascalCase with no underscores.
Aside from that, you have a lot of redundant code. The FinalProductPrice
doesn't sound like an appropriate property for a Product
type.
To answer the question about getting a collection of products that match a collection of ids, you can use LINQ:
string[] ids = ...;
List<Product> products = ...;
List<Product> matchingProducts =
products.Where(p => ids.Any(i => i == p.Id)).ToList();
Upvotes: 0