Home > Software design >  c# method with List / param int[] parameters
c# method with List / param int[] parameters

Time:09-20

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 Items 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]);
}
  •  Tags:  
  • c#
  • Related