I have to make method called CalculateBill with given parameters, but I cannot define how to connect those two parameters inside of code.
public class Bill {
public int CalculateBill (List<Item> itemList, params int[] items) {
// Need to write code here
//itemList : available items in the shop
// int[] items : array of ItemId's purchased by customer
// A customer can buy same item many times , so itemId can be repeated in items array
// return sum of al items prices
}
}
The item class is like
public class Item {
public int ItemId {get; set;}
public int ItemPrice { get; set; }
}
The Program Class is like
List<Item> itemList = new List<Item> {
new Item() {ItemId = 100 , ItemPrice = 50},
new Item() {ItemId = 101 , ItemPrice = 60},
new Item() {ItemId = 102 , ItemPrice = 20},
};
Bill bObj = new Bill();
int a = bObj.CalculateBill(itemList, 101, 102, 101);
int b = bObj.CalculateBill(itemList);
CodePudding user response:
It sounds like you need help implementing the CalculateBill function using your existing architecture. I would implement it like below.
I renamed your 'itemList' parameter to 'itemsInShop' and I also renamed your 'items' parameter to 'itemsPurchasedIDs'. Always try to make your variable names as descriptive as possible to make it easy to understand and read.
public int CalculateBill(List<Item> itemsInShop, params int[] itemsPurchasedIDs)
{
int totalSpent = 0;
for (int i = 0; i < itemsPurchasedIDs.Length; i )
{
int itemId = itemsPurchasedIDs[i];
for (int j = 0; j < itemsInShop.Count; j )
{
var shopItem = itemsInShop[j];
if (shopItem.ItemId == itemId)
{
totalSpent = shopItem.ItemPrice;
break;
}
}
}
return totalSpent;
}
CodePudding user response:
You are almost there. Create a class for the shop that contains the items available so you don't need to pass it as an argument.
Also, since you want to retrieve Item
s with id values, you need a Dictionary<int,Item>
which would allow you to do this quickly.
Here is the Shop
class with a dictionary
public class Shop
{
private readonly Dictionary<int, Item> _items;
public Shop()
{
_items = new Dictionary<int, Item>();
}
public IReadOnlyList<Item> Items { get => _items.Values.ToList(); }
public void Add(Item item) => _items.Add(item.ItemId, item);
public Item[] GetItems(params int[] idList)
{
List<Item> list = new List<Item>();
foreach (var id in idList)
{
list.Add(_items[id]);
}
return list.ToArray();
}
public decimal CalculateBill(params int[] idList)
{
var items = GetItems(idList);
decimal sum = 0m;
foreach (var item in items)
{
sum = item.ItemPrice;
}
return sum;
}
}
Otherwise, you would need to lookup the items one by one. Here is a solution that uses theList.Find()
method to match the Item
from the id
.
public class Shop
{
private readonly List<Item> _items;
public Shop()
{
_items = new List<Item>();
}
public IReadOnlyList<Item> Items { get => _items.ToList(); }
public void Add(Item item) => _items.Add(item);
public Item[] GetItems(params int[] idList)
{
List<Item> list = new List<Item>();
foreach (var id in idList)
{
list.Add(_items.Find((item)=>item.ItemId==id));
}
return list.ToArray();
}
public decimal CalculateBill(params int[] idList)
{
var items = GetItems(idList);
decimal sum = 0m;
foreach (var item in items)
{
sum = item.ItemPrice;
}
return sum;
}
}
CodePudding user response:
Here are three alternatives for you to try:
public int CalculateBill(List<Item> itemsInShop, params int[] itemsPurchasedIDs) =>
itemsPurchasedIDs
.Join(itemsInShop, id => id, item => item.ItemId, (_, item) => item.ItemPrice)
.Sum();
public int CalculateBill2(List<Item> itemsInShop, params int[] itemsPurchasedIDs) =>
(
from id in itemsPurchasedIDs
join item in itemsInShop on id equals item.ItemId
select item.ItemPrice
).Sum();
public int CalculateBill3(List<Item> itemsInShop, params int[] itemsPurchasedIDs)
{
var map = itemsInShop.ToDictionary(x => x.ItemId, x => x.ItemPrice);
return itemsPurchasedIDs.Sum(x => map[x]);
}