Michael Drum
Michael Drum

Reputation: 1239

How can I to filter a List of objects by the first occurrences of a List of properties?

Let's say I have the following code:

private class AccountRecord : IEquatable<AccountRecord>, IComparable<AccountRecord>
    {
        public Guid accountid { get; set; }
        public string accountnumber { get; set; }
        public string name { get; set; }
        public Guid ownerid { get; set; }
        public string owneridtype { get; set; }
        public int number { get; set; }
        public string companyname { get; set; }
        public AccountRecord(Guid accountid, string accountnumber, string name, Guid ownerid, string owneridtype, int number, string companyname)
        {
            this.accountid = accountid;
            this.accountnumber = accountnumber;
            this.name = name;
            this.ownerid = ownerid;
            this.owneridtype = owneridtype;
            this.number = number;
            this.companyname = companyname;
        }
        public bool Equals(AccountRecord other)
        {
            if(this.name.Equals(other.name) && this.number == other.number){
                return true;
            }
            else
            {
                return false;
            }
        }
        public int CompareTo(AccountRecord other)
        {
            if (this.number > other.number)
            {
                return 1;
            }
            else if (this.number < other.number)
            {
                return -1;
            }
            else
            {
                return 0;
            }
        }
    }

Somewhere else I have a List of these objects:

private List<AccountRecord> accountRecords = new List<AccountRecord>();

And I add several objects to the list:

accountRecords.Add(new AccountRecord(
                Row.accountid, 
                Row.accountnumber, 
                name, 
                Row.ownerid, 
                Row.owneridtype, 
                number,
                companyname));

I then get a list of distinct values for the 'companyname' property.

List<string> distinctCompanynames = accountRecords.Distinct(x => x.companyname).ToList<string>();

I'd like to get a List of AccountRecord objects with the highest 'number' property for each distinct 'companyname' property. Thanks to the work that I have done, I can do this with a nested for loop but my entire approach doesn't seem like the best approach considering all the tools C# has at it's disposal. This list will eventually get very large and this code will be executed frequently so I must do this as efficiently as possible. How can I do this faster/better than my current method?

My current method is:

  1. Make List of AccountRecords
  2. Sort
  3. (Reverse) Rewriting the CompareTo method of AccountRecord can remove this step.
  4. Make List of distinct 'companyname' values in List of AccountRecords
  5. Hard-code a nested for loop to perform some action on the first existence of an AccountRecord with each distinct 'companyname'.

What I'd like the method to be:

  1. Make List of AccountRecords
  2. Get a new list (or filter this list into becoming) a List of AccountRecord objects with the highest 'number' property for each distinct 'companyname' property.

If you have any questions, then please let me know.

Upvotes: 0

Views: 178

Answers (1)

James Curran
James Curran

Reputation: 103515

I haven't tested this, but this should work:

from ac in accountRecords
group ac by ac.companyname into company
select new
{
    Company = company.Key,
    Number = company.OrderByDescending(g => g.number).FirstOrDefault()
}

UPDATE: Read the question a bit more closely. It can be simplifed:

List<AccountRecord> highestRecords = 
   (from ac in accountRecords
    group ac by ac.companyname into company
    select company.OrderByDescending(g => g.number).FirstOrDefault())
   .ToList();

Upvotes: 1

Related Questions