Hank
Hank

Reputation: 2616

Group with linq on multiple properties via grouping method

I have the following code:

var linqResults = (from rst in QBModel.ResultsTable
            group rst by GetGroupRepresentation(rst.CallerZipCode, rst.CallerState) into newGroup
            select newGroup
           ).ToList();

With the grouping method:

private string[] GetGroupRepresentation(string ZipCode, string State)
{
  string ZipResult;
  if (string.IsNullOrEmpty(ZipCode) || ZipCode.Trim().Length < 3)
    ZipResult = string.Empty;
  else
    ZipResult = ZipCode.Substring(0, 3);

  return new string[]{ ZipResult, State };
}

This runs just fine but it does not group at all. The QBModel.ResultsTable has 427 records and after the linq has run linqResults still has 427. In debug I can see double-ups of the same truncated zip code and state name. I'm guessing it has to do with the array I'm returning from the grouping method.

What am I doing wrong here?

If I concatenate the return value of the truncated zip code and state name without using an array I get 84 groupings.

If I strip out the rst.CallerState argument and change the grouping method to:

private string GetGroupRepresentation(string ZipCode)
{
    if (string.IsNullOrEmpty(ZipCode) || ZipCode.Trim().Length < 3)
      return string.Empty;
    return ZipCode.Substring(0, 3);
}

It will return me 66 groups

I don't really want to concatenate the group values as I want to use them seperately later, this is wrong as it is based on if the array worked, however, kind of like the following:

List<DataSourceRecord> linqResults = (from rst in QBModel.ResultsTable
        group rst by GetGroupRepresentation(rst.CallerZipCode, rst.CallerState) into newGroup
        select new MapDataSourceRecord()
        {
          State = ToTitleCase(newGroup.Key[1]),
          ZipCode = newGroup.Key[0],
          Population = GetZipCode3Population(newGroup.Key[0])
        }).ToList();

Upvotes: 2

Views: 58

Answers (2)

Neil
Neil

Reputation: 666

Not sure if this will work because I can not replicate your code.
but maybe it will be easier to add a group key and your string[] in seperate variables before you go forth your grouping. like this.

var linqdatacleanup = QBModel.ResultsTable.Select(x=> 
new { 
     value=x,  
     Representation = GetGroupRepresentation(rst.CallerZipCode, rst.CallerState),
     GroupKey= GetGroupRepresentationKey(rst.CallerZipCode, rst.CallerState)
}).ToList();

so GetGroupRepresentationKey returns a single string and your GetGroupRepresentation returns your string[]

this will allow you to do your grouping on this dataset and access your data as you wanted.

but before you spend to much time on this check this stack overflow question. maybe it will help GroupBy on complex object (e.g. List<T>)

Upvotes: 0

Nabi Sobhi
Nabi Sobhi

Reputation: 369

Array is reference type, so when the grouping method compare two arrays with same values it can not determine they are the same, because the references are different. you can read more here

One solution would be considering a class instead of using an array for results of function, and use another class to compare your results implementing the IEqualityComparer Interface, and pass it to GroupBy method, so that the grouping method can find which combinations of ZipCode and State are really equatable. read more

Upvotes: 1

Related Questions