Select Distinct by Two Properties in a List

Select distinct by two properties in a list

LINQ to Objects doesn't provide this functionality easily in a built-in way, but MoreLINQ has a handy DistinctBy method:

messages = messages.DistinctBy(m => new { m.id, m.date }).ToList();

Linq select Distinct by two properties

You can use grouping, as much as it makes me cringe to use groupBy to do a distinct. You can just call First on the IGrouping to get one item out of the group, which is in effect a distinct. It will look something like this:

var distinctItems = data.GroupBy(item => new{
//include all of the properties that you want to
//affect the distinct-ness of the query
item.Property1
item.Property2
item.Property3
})
.Select(group => group.Key);
//if it's important that you have the low rank use the one below.
// if you don't care use the line above
//.Select(group => group.Min(item => item.Rank));

Distinct on multiple fields

Try with

GroupBy(
p => new {p.ItemName, p.SubItemName}
).Select(g => new { g.Key.ItemName, g.Key.SubItemName });

morelinq distinct by multiple properties

    list = list
.GroupBy(a=> new { a.id, a.parentid})
.Select(a=> a.first());

How to use LINQ Distinct() with multiple fields

I assume that you use distinct like a method call on a list. You need to use the result of the query as datasource for your DropDownList, for example by materializing it via ToList.

var distinctCategories = product
.Select(m => new {m.CategoryId, m.CategoryName})
.Distinct()
.ToList();
DropDownList1.DataSource = distinctCategories;
DropDownList1.DataTextField = "CategoryName";
DropDownList1.DataValueField = "CategoryId";

Another way if you need the real objects instead of the anonymous type with only few properties is to use GroupBy with an anonymous type:

List<Product> distinctProductList = product
.GroupBy(m => new {m.CategoryId, m.CategoryName})
.Select(group => group.First()) // instead of First you can also apply your logic here what you want to take, for example an OrderBy
.ToList();

A third option is to use MoreLinq's DistinctBy.

How to select multiple specific property with distinct value from javascript array

you can reduce the array and check every time if the pair exists:

data.reduce((prev, el) =>{
if(prev.some(o => o.group == el.group && o.testid == el.testid))
return prev;
return [...prev, {group:el.group, testid:el.testid}]
}, [])

const data = [   
{ group: 'A', name: 'SD', testid:1},
{ group: 'B', name: 'FI',testid:2 },
{ group: 'A', name: 'MM', testid:1 },
{ group: 'B', name: 'CO', testid:2 },
{ group: 'A', name: 'QW', testid:1 }
];
let result = data.reduce((prev, el) =>{
if(prev.some(o => o.group == el.group && o.testid == el.testid))
return prev;
return [...prev, {group:el.group, testid:el.testid}]
}, []);

console.log(result);

How to: Select Distinct objects<T> from multiple Lists<T> with 1 or more properties of same type

Seems like you need to use Enumerable.Union

var allManagers = d.Stores.Select(m => m.StoreManager).Union(d.Stores.Select(m => m.InventoryManager))
.Union(d.Warehouses.Select(m => m.WarehouseManager));
foreach (Manager m in allManagers)
{
Console.WriteLine("{0}:{1}", m.Id, m.Name);
}

Note that Union returns unique values from input sequences so no need to call Distinct.

LINQ's Distinct() on a particular property

EDIT: This is now part of MoreLINQ.

What you need is a "distinct-by" effectively. I don't believe it's part of LINQ as it stands, although it's fairly easy to write:

public static IEnumerable<TSource> DistinctBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> seenKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (seenKeys.Add(keySelector(element)))
{
yield return element;
}
}
}

So to find the distinct values using just the Id property, you could use:

var query = people.DistinctBy(p => p.Id);

And to use multiple properties, you can use anonymous types, which implement equality appropriately:

var query = people.DistinctBy(p => new { p.Id, p.Name });

Untested, but it should work (and it now at least compiles).

It assumes the default comparer for the keys though - if you want to pass in an equality comparer, just pass it on to the HashSet constructor.

Fastest way to select distinct values from list based on two properties

It looks like you are really after something like:

Dictionary<int, List<myobject>> myDataStructure;

That allows you to quickly retrieve by record number. If the List<myobject> with that dictionary key contains more than one entry, you can then use the name to select the correct one.

Note that if your list is not terribly long, an O(n) check that just scans the list checking for the recordNumber and name may be fast enough, in the sense that other things happening in your program could obscure the list lookup cost. Consider that possibility before over-optimizing lookup times.

LINQ Select Distinct objects from a List(Of T) on multiple properties does not work

You have a big flaw in your logic:

So from the above example I should be getting two objects only:

1) CreatedBy:1, GrantedTo: 65, PatientID: 48

2) CreatedBy:1, GrantedTo: 66, PatientID: 48

[...]

I believe the code should select the first from each unique group of objects.

Yes, you can get your data grouped by CreatedBy, GrantedTo and PatientID.

But what you get back cannot be (reasonable) objects of type Access and it will not be the first from each group.

Why? Because when you want to select all data from your object - and thus AccessID, PermissionID etc. - what values should those attributes have?

In your example 1):

Should AccesID be 238 or 240?

Should PermissionID be 15 or 18?

...

I guess you got the point.

So what you actually should do is to select the grouped data only, not as Access objects but either as an anonymous type or an defined type.

Anonymous version:

Dim distinct = From acc In access
Group By g = New With {Key .CreatedBy = acc.CreatedBy,
Key .GrantedTo = acc.GrantedTo,
Key .PatientID = acc.PatientID} Into Group

(The Key keyword is mandatory here!)

Now if you want to pass these distinct values to another object/function you can pass them as single paramaeters:

For Each value In distinct
foo.bar(value.g.CreatedBy, value.g.GrantedTo, value.g.PatientID)
Next

Or you create an own small class which contains only the three properties.
(I leave this point out since I´m running out of time but it should be straight forward).

EDIT

Try the following (typed blindly and untested):

Dim distinct = (From acc In access
Group By g = New With {Key .CreatedBy = acc.CreatedBy,
Key .GrantedTo = acc.GrantedTo,
Key .PatientID = acc.PatientID} Into Group
Select New Access With {.CreatedBy = g.CreatedBy,
.GrantedTo = g.GrantedTo,
.PateintID = g.PatientID}).ToList()

This should give you a List(Of Access) with new Access objects with only the three properties set.



Related Topics



Leave a reply



Submit