I'm trying to sort through a 2d list in C#. I have code written that lets me create a list from data pulled from a CSV file, however I'm stuck on the function to sort them.
The list details the shop ID, item, and price, and is formatted thusly:
1,shirt,5
1,pants,3
2,hat,3
I'm trying to find a way to take a user input, say 'shirt' and return the ID of the shop, and the price. How do I do this?
Here is the full code.
namespace Shop
{
public class ShopPick
{
private class Shop
{
public int ShopId { get; set; }
public Dictionary<string, decimal> Goods { get; set; }
}
private readonly List<Shop> _Shops = new List<Shop>();
public void ReadShopData(string filePath)
{
try
{
var records = File.ReadLines(filePath);
foreach (var record in records)
{
var data = record.Split(',');
var ShopId = int.Parse(data[0].Trim());
var Shop = _Shops.Find(r => r.ShopId == ShopId);
if (Shop == null)
{
Shop = new Shop { Goods = new Dictionary<string, decimal>() };
_Shops.Add(Shop);
}
Shop.ShopId = ShopId;
Shop.Goods.Add(data.Skip(2).Select(s => s.Trim()).Aggregate((a, b) => a.Trim() "," b.Trim()), decimal.Parse(data[1].Trim()));
}
}
catch (FileNotFoundException ex)
{
Console.WriteLine(ex.Message);
}
}
static void Main(string[] args)
{
var ShopPicker = new ShopPick();
ShopPicker.ReadShopData(
Path.GetFullPath(
Path.Combine(
AppDomain.CurrentDomain.BaseDirectory, @"../../../../Shop_data.csv")
)
);
// Item is found in Shop 2 at price 6.50
var bestShop = ShopPicker.PickBestShop("gac");
Console.WriteLine(bestShop.Item1 ", " bestShop.Item2);
Console.WriteLine("Done!");
Console.ReadLine();
}
public Tuple<int, decimal> PickBestShop(string items)
{
string input = Console.ReadLine();
string[] choices = input.Split(',');
foreach(var Shop in _Shops)
{
}
return new Tuple<int, decimal>(0, 0);
}
}
}
The function PickBestShop is where I am stuck
CodePudding user response:
You can use Linq statements. The following code will give you an IEnumerable with the single product Id. Of course you'll need to check for empty lists and nulls and things like that. The code is assuming a product has at least the fields Id and Name.
products.Where(product => product.Name == name).Select(product => product.Id)
CodePudding user response:
I made some edits based on what I could understand from your question. The content in c:\temp\shop.csv looks like:
1,shirt,5
1,pants,3
2,hat,3
3,shirt,6
3,hat,2
4,pants,2
3,trousers,20
5,shirt,5
5,hat,2
And this is edited code:
static void Main(string[] args)
{
//string fileName = Path.GetFullPath(Path.Combine(
// AppDomain.CurrentDomain.BaseDirectory, @"../../../../Shop_data.csv")
// );
string fileName = @"c:\temp\shops.csv";
var ShopPicker = new ShopPick(fileName);
var sample = ShopPicker.PickBestShop("shirt, Hat");
foreach (var shop in sample)
{
Console.WriteLine($"ShopId:{shop.ShopId}, Product: {shop.Product}, Price: {shop.Price}");
}
}
public class ShopPick
{
private List<Shop> _Shops;
public class Shop
{
public int ShopId { get; set; }
public string Product { get; set; }
public decimal? Price { get; set; }
}
public ShopPick(string filePath)
{
var records = File.ReadLines(filePath)
.Select(line => line.Split(','))
.Select(line => new Shop
{
ShopId = int.TryParse(line[0], out int sId) ? sId : -1,
Product = line[1].Trim(),
Price = decimal.TryParse(line[2], out decimal p) ? p : (decimal?)null
});
this._Shops = records.ToList();
}
//public List<Shop> Shops { get { return this._Shops; } }
public IEnumerable<Shop> PickBestShop(string items)
{
List<Shop> shops = new List<Shop>();
//string input = Console.ReadLine();
var choices = items.Split(',').Select(p => p.Trim().ToLower());
foreach (var item in choices)
{
var _shops = this._Shops.Where(s => s.Product.ToLower() == item);
if (_shops.Any())
{
var minPrice = _shops.Min(s => s.Price);
shops.AddRange(_shops.Where(s => s.Price == minPrice));
}
}
return shops;
}
}
Outputs:
ShopId:1, Product: shirt, Price: 5
ShopId:5, Product: shirt, Price: 5
ShopId:3, Product: hat, Price: 2
ShopId:5, Product: hat, Price: 2
Please inform if that wasn't what you meant and\or you require explanation on any part.
