Перебирая массивы, связывая значения друг с другом - PullRequest
0 голосов
/ 16 ноября 2018

В Visual Studio, используя C #, у меня есть три массива, которые выглядят примерно так:

int[] price = new int[] { 100, 200, 300, 400, 500, 600 };

string[] goods = new string[] { "item1", "item2", "item3", "item4", "item5", "item6" }; 

bool[] cart = new bool[] { false, false, false, false, false, false };

Логическая корзина представляет флажки. Теперь я хочу с помощью кнопки проверить, какие флажки отмечены, а затем отсортировать название элемента из массива товаров и цену его из цены массива. Затем я объединю строки, добавлю общую сумму и просто выведу ее в MessageBox.Show.

Я думаю, мне нужно как-то привязать индекс массива корзины к соответствующим индексам массивов цен и товаров. Или есть лучший способ сделать это? А за цикл наверное, но как? Я не уверен, с чего начать. Помощь с благодарностью!

Ответы [ 6 ]

0 голосов
/ 16 ноября 2018

Хотя кодирование в C #, вы не объектно-ориентированные.

Я согласен с комментарием @ JoelCoehoorn о вашем текущем коде, демонстрирующем анти-паттерн. Ниже мое решение для этого с помощью объектной ориентации.


  • Поскольку price и good ссылаются на один и тот же объект, создайте класс Item и добавьте к нему члены String Name; и double Price;.

  • Поскольку есть Cart, я уверен, что корзина в магазине. Итак, создайте класс Store.

    • В классе Store добавьте Dictionary<int, Item> AvailableItems;, в котором перечислены все предметы, доступные в магазине (вместо словаря можно использовать и другие DS, что имеет смысл в вашем случае).
  • Далее, покупателям, которые приходят в ваш магазин за покупками, должен быть присвоен уникальный идентификатор. Это требует Customer класса. (Гостевым пользователям может быть назначен новый случайный идентификатор).

    • У клиентов также будет Dictionary<int, int> Cart;, который является отображением идентификатора предмета, который они хотят приобрести, и количества предметов.
  • Наконец, мы подходим к объекту Order, который принимает Cart и имеет хороший метод, называемый PrintTotalSumFrom(Cart c), который делает именно то, что вы думаете.


Полезный ответ, который я написал некоторое время назад об объектно-ориентированных принципах: здесь .

0 голосов
/ 16 ноября 2018

Вы можете попробовать создать класс Good со свойствами Name, Price, Cart и т. Д.

public class Good
{
    public string Name { get; set; }
    public int Price { get; set; }
    public bool Cart { get; set;}

 }

и затем поместить их в список.

List<Good> MyGoods = new List<Good>();
MyGoods.Add(new Good{ Name="item1", Price=100, Cart = false});

Вы можете добавить столько элементов, сколько захотите, в этот список, а затем итерировать их с помощью индекса или foreach

for(int i=0; i<MyGoods.Count;i++)
{
    Console.WriteLine(MyGoods[i].Name);
}

или

foreach(Good g in MyGoods)
{
    Console.WriteLine(g.Name);
}
0 голосов
/ 16 ноября 2018

Как и предполагали другие, использование модели данных или словаря было бы определенно лучше, но если вы хотите придерживаться своего исходного кода использования массивов, то вы можете использовать следующий код:

int[] price = new int[] { 100, 200, 300, 400, 500, 600 };

string[] goods = new string[] { "item1", "item2", "item3", "item4", "item5", "item6" };

bool[] cart = new bool[] { false, false, false, false, false, false };

StringBuilder sb = new StringBuilder();
int totalPrice = 0;
for(int i = 0; i < cart.Length; i++)
{
    if (!cart[i]) continue;
    sb.Append(goods[i]);
    totalPrice += price[i];
}
//Use sb.ToString() and totalPrice to show in Messagebox.
0 голосов
/ 16 ноября 2018

Это простой пример проблемы связывания.

Я предполагаю, что у вас есть флажок для каждого из ваших предметов, и когда его состояние изменяется, bool[] cart изменяется с правильным индексом.

Тогда вам просто нужно сохранить этот индекс и сложить правильную цену и товар, как это:

string shoppingCart += goods[i];

decimal cost += price [i];

Но, и это очень важно, вам не следует полагаться на так много массивов, основанных на индексе.

Как упомянуто в его комментарии icebat , вы должны реализовать класс, представляющий ваши предметы.

Пример:

public class Item
{
    public int Id { get; set; }
    public decimal Price { get; set; }
    public string Name { get; set; }
}
0 голосов
/ 16 ноября 2018

Вы обязательно должны создать объект, который описывает товары в продаже.

однако, если вы хотите вместе взломать ужас, вы можете сделать что-то вроде этого ...

int[] price = new int[] { 100, 200, 300, 400, 500, 600 };

string[] goods = new string[] { "item1", "item2", "item3", "item4", "item5", "item6" }; 

bool[] cart = new bool[] { false, false, true, false, false, true };

var selected = cart.Select((value,index) => new {value, index})
    .Where(item => item.value == true)
    .Select(item => item.index)
    .ToList();

int total = 0;

foreach(var x in selected){
    total += price[x];
}

//total is 900
0 голосов
/ 16 ноября 2018

есть ли лучший способ сделать это?

Совпадающий массив, подобный этому, является анти-шаблоном и признаком того, что вы действительно должны создать класс со свойствами для цены, товара и корзины. Тогда у вас может быть один массив, который вы можете просмотреть только один раз.

Но вы все равно можете делать то, что вам нужно, даже с этим анти-паттерном:

var items = cart.Zip(goods, (c,g) => new {Cart = c, Good = g}).Zip(price, (a, p) => new {Cart = a.Cart, Good = a.Good, Price = p});
var ticked = items.Where(i => i.Cart);

var message = string.Join(",", ticked.Select(t => t.Good));
var sum = ticked.Select(t => t.Price).Sum();

MessageBox.Show($"{message}\nTotal: {sum}");

Это также будет работать и может означать меньшее использование памяти:

var ticked = cart.Select((value,index) => new {Cart = value, Price = price[index], Good = goods[index]})
    .Where(i => i.Cart);
var message = string.Join(",", ticked.Select(s => s.Good));
var sum = ticked.Select(s => s.Price).Sum();

MessageBox.Show($"{message}\nTotal: {sum}"); 

Вы также можете использовать индексы:

int sum = 0;
var message = new StringBuilder();
var delimiter = "";
for(int i = 0; i<cart.Length; i++)
{
    if (cart[i])
    {
       sum += price[i];
       message.Append(delimiter).Append(goods[i]);
       delimiter = ",";
    }
}
MessageBox.Show($"{message}\nTotal: {sum}");

И в этом случае опция индекса, вероятно, быстрее и не сложнее для понимания опции linq (хотя очень часто наоборот), даже если это больше кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...