Как объединить элементы списка - PullRequest
2 голосов
/ 09 марта 2010

Я работаю в C #. У меня есть отсортированный список структур. Структура имеет объект DateTime, в котором хранятся месяц и год, и целое число, в котором хранится значение. Список отсортирован по дате. Мне нужно просмотреть список и объединить его, чтобы у меня был только один экземпляр структуры на дату.

Например: Мой первоначальный список будет выглядеть так:

{ (Apr10, 3), (Apr10, 2), (Apr10, -3), (May10, 1), (May10, 1), (May10, -3), (Jun10, 3) } 

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

{ (Apr10, 2), (May10, -1), (Jun10, 3) }

Я ищу простое / эффективное решение.

Структура:

struct CurrentTrade
{
    public DateTime date;
    public int dwBuy;
}

Список:

private List<CurrentTrade> FillList

Ответы [ 5 ]

6 голосов
/ 09 марта 2010

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

var newList = (
    from trade in FillList
    group trade by trade.Date.Date into g
    select new CurrentTrade { date = g.Key, dwBuy = g.Sum(t => t.dwBuy) }
).ToList();
2 голосов
/ 09 марта 2010

Если вы не хотите использовать LINQ:

Если список отсортирован по датам, то все элементы с одинаковыми датами располагаются рядом друг с другом. Вы можете сделать что-то вроде этого:

for ( int i = FillList.Count - 1; i >= 1; i-- ) {
    if ( FillList[i].date == FillList[i-1].date ) {
       FillList[i-1].dwBuy += FillList[i].dwBuy;
       FillList.RemoveElementAt( i );
    }
}

Однако рекомендуется решение LINQ, если оно поддерживается в .NET.

Если входные даты включают компонент времени и вы хотите объединить дату, просто измените оператор if с:

if ( FillList[i].date == FillList[i-1].date )

до

if ( FillList[i].date.Date == FillList[i-1].date.Date )
1 голос
/ 09 марта 2010
var result  = FillList.GroupBy(x => x.date)
                      .Select(g => new CurrentTrade { 
                          date = g.Key, 
                          dwBuy = g.Sum(x => x.dwBuy) 
                      })
                      .ToList();

Edit:

Если CurrentTrade содержит компонент времени, вы должны преобразовать его в объект DateTime только с датой:

var result  = FillList.GroupBy(x => x.date.Date)
                      .Select(g => new CurrentTrade { 
                          date = g.Key, 
                          dwBuy = g.Sum(x => x.dwBuy) 
                      })
                      .ToList();
1 голос
/ 09 марта 2010

Посмотрите на операторы LINQ .

0 голосов
/ 09 марта 2010

Как насчет использования HashSet<T>? HashSets не может содержать один и тот же объект дважды. Однако для этого может потребоваться переопределить метод GetHash в вашем классе CurrentTrade.

(Хотя что-то простое, как return Date.GetHashCode() ^ dwBug может сделать это.)

...