简体   繁体   中英

Linq Groupby categorizes but how do I manipulate the values in the collection

I have an observable collection Auctions which is of Type Auction which looks like

public class Auction
{
     public int GroupId {get; set;}
     public DateTime Date {get; set;}
     public string Hour {get; set;}
     public decimal Offer {get; set;}
     public decimal Bid {get; set;}
     public decimal OfferPrice {get; set;}
     public decimal BidPrice {get; set;}
}

The collection contains the following data,

Group Id    Date    Hour    Offer   Bid Offer Price Bid Price
1   27/06/2013  00:00   5.556   86.3    250 0
1   27/06/2013  00:15   0   0   250 0
1   27/06/2013  00:30   0   0   250 0
1   27/06/2013  00:45   0   0   250 0
1   27/06/2013  01:00   0   0   250 0
1   27/06/2013  01:15   5.556   86.3    250 0
2   27/06/2013  01:30   8.68    19.9    100 20
2   27/06/2013  01:45   0   0   100 20
2   27/06/2013  02:00   8.68    19.9    100 20
2   27/06/2013  02:15   0   0   100 20
2   27/06/2013  02:30   8.68    19.9    100 20
2   27/06/2013  02:45   0   0   100 20
2   27/06/2013  03:00   8.68    19.9    100 20
3   27/06/2013  03:15   87.14   87.1    150 0
3   27/06/2013  03:30   0   0   150 0
3   27/06/2013  03:45   0   0   150 0
3   27/06/2013  04:00   0   0   150 0
3   27/06/2013  04:15   0   0   150 0
3   27/06/2013  04:30   0   0   150 0
3   27/06/2013  04:45   0   0   150 0
3   27/06/2013  05:00   0   0   150 0

Now what I am trying to do is,

  • Group collection by GroupId, so I get 3 blocks one with GroupId = 1, GroupId =2 and GroupId = 3.
  • I then need to set everything that is not in Group 1 to zero and add it to group 1.

Example,

  • Everything which is group 1 in green color is copied as is, then group 1 is appended with the rest of the data but set to zero.
  • Similarly for group 2 and for group 3.

在此处输入图片说明

What is the best way to do this via Linq?

The collection that the result needs to be added to is of type BOD and it contains

Public class BOD
{
    public DateTime Date {get; set;}
    public string Time {get; set;}
    public decimal Volume {get; set;}
    public decimal Price {get; set;}
}

You can try something like that:

var list = new List<YourType>(); // Your data source
var groupedList = list.GroupBy(listEntry => listEntry.GroupId);

foreach(var groupList in groupedList)
{
   var unionList = groupList.ToList()
       .Union(list.Where(listEntry => listEntry.GroupId != groupList.Key)
       .Select(listEntry => new YourType { GroupId = groupList.Key, a = 0, b = 0, c = listEntry.c }))
}

You can join the list of auctions to a unique list of GroupIds:

var q = (from a in Auctions
         from g in (Auctions.Select(aa=>aa.GroupId).Distinct())
         orderby g, a.Date, a.Hour
         select new Auction
             {
                  GroupId = g,
                  Date = a.Date,
                  Hour = a.Hour,
                  Offer      = a.GroupId == g ? a.Offer : 0,
                  Bid        = a.GroupId == g ? a.Bid : 0,
                  OfferPrice = a.GroupId == g ? a.OfferPrice : 0,
                  BidPrice   = a.GroupId == g ? a.BidPrice : 0
              }

Something like this should work:

var group1 =
            (from a in auctions where a.GroupId == 1 select a).Union(
                from a in auctions
                where a.GroupId != 1
                select new Auction { GroupId = 1, Date = a.Date, Hour = a.Hour });

The new Auction will contain zeros unless you specifically copy them across. You'd want to get rid of the hard coded ids but that wouldn't be difficult to sort out.

I'm not sure I got you right about adding items from other groups, but take a look at this queries:

var auctions = new List<Auction>
{
    new Auction {GroupId = 1, Date = DateTime.Parse("27/06/2013"), Hour = "00:00", Offer = 5.556m, Bid = 86.3m, OfferPrice = 250m, BidPrice = 0m},
    new Auction {GroupId = 1, Date = DateTime.Parse("27/06/2013"), Hour = "00:15", Offer = 0m, Bid = 0m, OfferPrice = 250m, BidPrice = 0m},
    new Auction {GroupId = 1, Date = DateTime.Parse("27/06/2013"), Hour = "00:30", Offer = 0m, Bid = 0m, OfferPrice = 250m, BidPrice = 0m},
    new Auction {GroupId = 1, Date = DateTime.Parse("27/06/2013"), Hour = "00:45", Offer = 0m, Bid = 0m, OfferPrice = 250m, BidPrice = 0m},
    new Auction {GroupId = 1, Date = DateTime.Parse("27/06/2013"), Hour = "01:00", Offer = 0m, Bid = 0m, OfferPrice = 250m, BidPrice = 0m},
    new Auction {GroupId = 1, Date = DateTime.Parse("27/06/2013"), Hour = "01:15", Offer = 5.556m, Bid = 86.3m, OfferPrice = 250m, BidPrice = 0m},
    new Auction {GroupId = 2, Date = DateTime.Parse("27/06/2013"), Hour = "01:30", Offer = 8.68m, Bid = 19.9m, OfferPrice = 100m, BidPrice = 20m},
    new Auction {GroupId = 2, Date = DateTime.Parse("27/06/2013"), Hour = "01:45", Offer = 0m, Bid = 0m, OfferPrice = 250m, BidPrice = 20m},
    new Auction {GroupId = 2, Date = DateTime.Parse("27/06/2013"), Hour = "02:00", Offer = 8.68m, Bid = 19.9m, OfferPrice = 100m, BidPrice = 20m},
    new Auction {GroupId = 2, Date = DateTime.Parse("27/06/2013"), Hour = "02:15", Offer = 0m, Bid = 0m, OfferPrice = 100m, BidPrice = 20m},
    new Auction {GroupId = 2, Date = DateTime.Parse("27/06/2013"), Hour = "02:30", Offer = 8.68m, Bid = 19.9m, OfferPrice = 100m, BidPrice = 20m},
    new Auction {GroupId = 2, Date = DateTime.Parse("27/06/2013"), Hour = "02:45", Offer = 0m, Bid = 0m, OfferPrice = 100m, BidPrice = 20m},
    new Auction {GroupId = 2, Date = DateTime.Parse("27/06/2013"), Hour = "03:00", Offer = 8.68m, Bid = 19.9m, OfferPrice = 100m, BidPrice = 20m},
    new Auction {GroupId = 3, Date = DateTime.Parse("27/06/2013"), Hour = "03:15", Offer = 87.14m, Bid = 87.1m, OfferPrice = 150m, BidPrice = 0m},
    new Auction {GroupId = 3, Date = DateTime.Parse("27/06/2013"), Hour = "03:30", Offer = 0m, Bid = 0m, OfferPrice = 150m, BidPrice = 0m},
    new Auction {GroupId = 3, Date = DateTime.Parse("27/06/2013"), Hour = "03:45", Offer = 0m, Bid = 0m, OfferPrice = 150m, BidPrice = 0m},
    new Auction {GroupId = 3, Date = DateTime.Parse("27/06/2013"), Hour = "04:00", Offer = 0m, Bid = 0m, OfferPrice = 150m, BidPrice = 0m},
    new Auction {GroupId = 3, Date = DateTime.Parse("27/06/2013"), Hour = "04:15", Offer = 0m, Bid = 0m, OfferPrice = 150m, BidPrice = 0m},
    new Auction {GroupId = 3, Date = DateTime.Parse("27/06/2013"), Hour = "04:30", Offer = 0m, Bid = 0m, OfferPrice = 150m, BidPrice = 0m},
    new Auction {GroupId = 3, Date = DateTime.Parse("27/06/2013"), Hour = "04:45", Offer = 0m, Bid = 0m, OfferPrice = 150m, BidPrice = 0m},
    new Auction {GroupId = 3, Date = DateTime.Parse("27/06/2013"), Hour = "05:00", Offer = 0m, Bid = 0m, OfferPrice = 150m, BidPrice = 0m}
};

// Create 2 BOD object for each Auction
var b1 =
        from a in auctions
        from b in new List<BOD> {
                new BOD { Date = a.Date, Time = a.Hour, Price = a.BidPrice, Volume = a.Bid },
                new BOD { Date = a.Date, Time = a.Hour, Price = a.OfferPrice, Volume = a.Offer } 
        }
        select b;

// Create 2 BOD object with zero price and volume for each Auction with another GroupId
var b2 =
        from d in auctions.Select(x => x.GroupId)
        from a in auctions.Where(y => y.GroupId != d)
        from b in new List<BOD> {
                new BOD { Date = a.Date, Time = a.Hour, Price = 0, Volume = 0 },
                new BOD { Date = a.Date, Time = a.Hour, Price = 0, Volume = 0 } 
        }
        select b;

var bods = b1.Union(b2);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM