Сравнивая по одному элементу с объектом в списке? - PullRequest
1 голос
/ 26 января 2012

У меня есть собственный класс, содержащий 2 открытые переменные: 1 - строка, а 1 - целое число. Затем я делаю список этого класса, в списке мне нужно, чтобы строка класса была уникальной, если строка уже существует в списке, я не хочу добавлять ее снова, но хочу объединить соответствующие целые числа. Вот пример пользовательского класса и списка.

public class myItems
{
    public string itemName;
    public int count;
}

List<myItems> items = new List<myItems>();

myItems e = new myItems();
e.symbol = "pencil";
e.count = 3;
items.Add(e);

myItems e1 = new myItems();
e1.symbol = "eraser";
e1.count = 4;
items.Add(e1);

myItems e2 = new myItems();
e1.symbol = "pencil";
e1.count = 3;
items.Add(e5);

Итак, для окончательного списка я хочу, чтобы он содержал: карандаш 7, ластик 4. Я использовал функцию содержимого в списке, чтобы проверить, существует ли он, но он возвращает значение true, только если строка и целое число совпадают .

Есть ли способ сопоставить только строку?

Ответы [ 5 ]

2 голосов
/ 26 января 2012

Другой способ сделать это - использовать LINQ:

public class myItems
{
    public string itemName;
    public int count;
}

List<myItems> items = new List<myItems>();

myItems e = new myItems();
e.symbol = "pencil";
e.count = 3;
Add(items, e);

myItems e1 = new myItems();
e1.symbol = "eraser";
e1.count = 4;
Add(items, e1);

myItems e2 = new myItems();
e1.symbol = "pencil";
e1.count = 3;
Add(items, e5);

public void Add(List<myItems> list, myItems newItem)
{
    var item = list.SingleOrDefault(x => x.symbol == newItem.symbol);

    if(item != null)
    {
        item.count += newItem.count;
    }
    else
    {
        list.Add(newItem);
    }
}
1 голос
/ 26 января 2012

Вы можете добавить метод Equals в свой класс или использовать LINQ с чем-то вроде

items.Where(i => i.itemName == "pencil")

Однако, если все, что вы делаете, отслеживает, сколько у вас «предметов», будет словарьчто сопоставляет itemNames с графами, чтобы решить вашу проблему проще?Тогда вы сможете делать такие вещи, как

// Assuming you want to add a new 'pencil' with a count of 3
int oldCount = 0;
items.TryGetValue("pencil", out oldCount);

items["pencil"] = oldCount + 3;

Обычно вы видите что-то вроде этого под названием сумка

1 голос
/ 26 января 2012

Для этой проблемы вполне подойдет словарь:

readonly Dictionary<string, int> _dict = new Dictionary<string, int>();

void InsertOrUpdate(string name, int count)
{
    int previousCount = 0;

    // item already in dictionary?
    if (_dict.TryGetValue(name, out previousCount))
    {
        // add to count
        count += previousCount;
    }

    _dict[name] = count;
}

void Main()
{
    InsertOrUpdate("pencil", 3);
    InsertOrUpdate("eraser", 3);
    InsertOrUpdate("pencil", 4);

    // print them
    foreach (var item in _dict)
        Console.WriteLine(item.Key + " " + item.Value);
}
0 голосов
/ 26 января 2012

Конечно, напишите пользовательский Equals метод

public override bool Equals(object o)
{
    MyItems mi = o as MyItems;
    if (mi == null)
        return false;
    if (itemName == null)
        return mi.itemName == null;
    return itemName.Equals(mi.itemName);
}

public override int HashCode()
{
    return (itemName ?? string.Empty).HashCode();
}

При этом вам действительно следует вместо этого использовать словарь / хэш-таблицу, поскольку словарь обеспечивает намного более быстрый поиск, когда вы знаете, что хотите. Реализация List приведет к тому, что список будет просматриваться целиком каждый раз, когда вы захотите добавить MyItem в список.

0 голосов
/ 26 января 2012

когда вы проверяете, содержит ли оно значение true и возвращается ли оно, вы получаете индекс и добавляете к нему число. использовать эту логику. это будет работать.

...