开发者

Take the highest bid by this user

I'm building an auction site and the user can bid on the same item more than once (obviously). In the user's dashboard, a user can view his bids. When the user bids on the same item more than once, I want only one entry with the highest bid value to show up. My current code shows an entry for each bid. I tried a few things but I couldn't figure it out. Here's what I've got:

public class Bid
{
    public int Id { get; set; }
    public double Amount { get; set; }
    public DateTime Date { get; set; }
    public virtual Item Item { get; set; }
    public virtual User User { get; set; }
}

    protected override List<ItemForUserBids> ResolveCore(User source)
    {
        var items = new List<ItemForUserBids>();
        var userBids = source.Bids;
        foreach (var bid in userBids)
        {
            var item = bid.Item;
            var c = new ItemForUserBids
                        {
                            BidValue = bid.Amount,
                            BidId = bid.Id,
                            Description = item.Description,
                            Id = item.Id,
                            ItemThumb = item.MainImageLink(),
                            Status = _itemsService.GetBiddingStatus(item, source),
                            TimeLeft = item.EndDate.TimeLeft(),
                            Title = item.Title
                        };
            items.Add(c);
        }
        return items;
    }

I tried to get Distinct bids based on the Item.Id but that did not work. Now I'm thinking maybe I could use the Date property of the Bid entity somehow to get to the result I want but my head stopped thinking.

Any suggestions?

UPDATE:

I got it to work using a dictionary and using OrderBy() and Max() like many suggested. But I think the latter could be further improved.

Implementation using a dictionary (works):

    var userBids = new Dictionary<string, Bid>();

    foreach (var bid in allUserBids)
    {
        var key = bid.Item.Id.ToString();
        if(userBids.ContainsKey(key))
        {
            if (userBids[key].Amount < bid.Amount)
                userBids[key] = bid;
        }
        userBids[key] = bid;
    }

Attempt using the other method (works):

    var highestBids =
        source.Bids.Where(x => x.Date > DateTime.Now.AddYears(-1))
                    .GroupBy(x => x.Item.Id,
                                            (itemId, bids) =>
                                            new
                                                {
                                                    ItemId = itemId,
                                                    MaxBid = bids.Max(x => x.Amount)
                                                }).T开发者_如何学编程oList();
    var userBids = new List<Bid>();
    foreach (var bid in source.Bids)
    {
        for(var i = 0; i < highestBids.Count; i++)
        {
            var curr = highestBids[i];
            if (bid.Item.Id.Equals(curr.ItemId) && bid.Amount.Equals(curr.MaxBid)) {
                userBids.Add(bid);
                highestBids.Remove(curr);
            }
        }
    }

How do I get rid of those loops? And maybe have it all in one chained statement?


The comments posted so far should be a good indication that you should look into re-architecting this a little, but the immediate code solution involves using System.Linq to chain together a GroupBy, Max, and a Select.


you could simply create a dictionary of user bids, where the key is the item id. Then for each user bid if an item id is not already used then add the current bid to the dictionary, if it is used then see if the bid amount of the item that exists in the dictionary already is lower than the current item then replace the existing item in the dictionary with the current one.

However this is very inefficient as really you only want to load the top 1 bid sorted descending by bid amount for each bid id, not load all the bids then work out the highest. What happens if your user has 10,000 old bids? Do they all get loaded?

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜