开发者

How to combine elements of a list

I'm working in c#. I have a sorted L开发者_Go百科ist of structures. The structure has a DateTime object which stores month and year and an integer which stores a value. The list is sorted by date. I need to traverse the list and combine it so that I only have one instance of the structure per date.

For example: My initial list would look like this:

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

The resulting list should look like this:

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

I'm looking for a simple / efficient solution.

The struct is:

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

The list is:

private List<CurrentTrade> FillList


You can use 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();


If you don't want to use LINQ:

If the list is sorted by dates, then all the items with the same dates are next to each other. You can do something like this:

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 );
    }
}

The LINQ solution is recommended though, if your .NET supports it.

If the input dates include the time component and you want to merge on the date, just change the if statement from:

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

to

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


Look at LINQ statements.


var result  = FillList.GroupBy(x => x.date)
                      .Select(g => new CurrentTrade { 
                          date = g.Key, 
                          dwBuy = g.Sum(x => x.dwBuy) 
                      })
                      .ToList();

Edit:

If CurrentTrade does contain a time component you should convert it to a date only DateTime object:

var result  = FillList.GroupBy(x => x.date.Date)
                      .Select(g => new CurrentTrade { 
                          date = g.Key, 
                          dwBuy = g.Sum(x => x.dwBuy) 
                      })
                      .ToList();


What about using a HashSet<T>? HashSets can't contain the same object twice. That may however require you to reimplement the GetHash method in your CurrentTrade class.

(Something easy like return Date.GetHashCode() ^ dwBug could do it though.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜