19

I am stumped. I need help. I have a DTO object with duplicates patient address data. I need to get only the unique addresses.

Dim PatientAddressDto = New List(Of PatientAddress)

{Populate PatientAddressDto with lots of duplicate data}

PatientAddressDto = (From d In PatientAddressDto
                    Group d By PatientAddressDtoGrouped = New PatientAddress With {
                                                              .Address1 = d.Address1,
                                                              .Address2 = d.Address2,
                                                              .City = d.City,
                                                              .State = d.State,
                                                              .Zip = d.Zip
                                                              }
                  Into Group
                  Select New PatientAddress With {
                                                  .Address1 = PatientAddressDtoGrouped.Address1,
                                                  .Address2 = PatientAddressDtoGrouped.Address2,
                                                  .City = PatientAddressDtoGrouped.City,
                                                  .State = PatientAddressDtoGrouped.State,
                                                  .Zip = PatientAddressDtoGrouped.Zip
                                                  }).ToList()

I have tried the following with no luck:

PatientAddressDto = (From d In PatientAddressDto
                    Select New PatientAddress With {
                                                  .Address1 = d.Address1,
                                                  .Address2 = d.Address2,
                                                  .City = d.City,
                                                  .State = d.State,
                                                  .Zip = d.Zip
                                                    }).Distinct     

and also

PatientAddressDto = PatientAddressDto.GroupBy(Function(p) New PatientAddress With {
                                                  .Address1 = p.Address1,
                                                  .Address2 = p.Address2,
                                                  .City = p.City,
                                                  .State = p.State,
                                                  .Zip = p.Zip
                                                    })
wavedrop
  • 520
  • 1
  • 4
  • 15

3 Answers3

28

You can use an anonymous type and make use of the Key keyword in order for equality to behave the way you expect (not required for C#).

Change your grouping by specifying the Key prefix and remove the PatientAddress usage :

Group d By PatientAddressDtoGrouped = New With {
    Key .Address1 = d.Address1,
    Key .Address2 = d.Address2,
    Key .City = d.City,
    Key .State = d.State,
    Key .Zip = d.Zip
}
Ahmad Mageed
  • 94,561
  • 19
  • 163
  • 174
  • Thank you for the tip. I am getting an error however stating that the name or property being initialized must begin with '.'. – wavedrop Apr 03 '12 at 16:34
  • 1
    @wavedrop updated. You need to remove the `PatientAddress` in your `New` declaration while grouping so that you use an anonymous type. – Ahmad Mageed Apr 03 '12 at 16:40
  • It's not any anonymous type. The type is "Patient Address" – wavedrop Apr 03 '12 at 16:44
  • 1
    @wavedrop right, but for the purpose of the grouping you can change the code as suggested above to use an anonymous type and get distinct results as expected. Your final `Select New PatientAddress` statement will ensure that the result in the end will be the class. Otherwise, you will need to modify your `PatientAddress` class and implement `IEqualityComparer`. That might be worth the effort if you intend to do lots of similar groupings and distinct calls, but with grouping we can use this shortcut. – Ahmad Mageed Apr 03 '12 at 16:49
  • interesting that the equivalent code in c# is more basic than a language that claims to be basic... – jtate Jan 08 '20 at 16:58
5

I have found the following code to work which essentially accomplishes the grouping that I desire and populating the new object as type PatientAddress therefore eliminating the use of anonymous objects and the keyword Key.

Maybe someone can explain it, at the moment I can not. Have a nice day.

Dim PatientAddressDto = New List(Of PatientAddress)

{Populate PatientAddressDto with lots of duplicate data}

PatientAddressDto = (From d In PatientAddressDto
                    Group d By d.Address1,
                                d.Address2,
                                d.City,
                                d.State,
                                d.Zip Into g =
                    Group Let grp = New PatientAddress With {.Address1 = Address1,
                                                                .Address2 = Address2,
                                                                .City = City,
                                                                .State = State,
                                                                .Zip = Zip}
                    Select grp).ToList()
wavedrop
  • 520
  • 1
  • 4
  • 15
3

Its probably because PatientAddress does not override GetHashCode and Equals. An alternative is to us an anonymous type for the grouping. Try writing:

Group d By PatientAddressDtoGrouped = New With { Key .Address1 = d.Address1, ....
Magnus
  • 45,362
  • 8
  • 80
  • 118
  • do you have a recommendation? – wavedrop Apr 03 '12 at 16:29
  • I've updated the answer. Try using an anonymous type instead of an existing class. – Magnus Apr 03 '12 at 16:40
  • Thank you that worked and was very helpful. I marked Ahmads as the answer because I could only pick one, it was slightly more helpful, and I think he had the final answer first (before your edit). Thanks again. – wavedrop Apr 03 '12 at 17:04