Using Linq Except Not Working as I Thought

Using Linq Except not Working as I Thought

If you are storing reference types in your list, you have to make sure there is a way to compare the objects for equality. Otherwise they will be checked by comparing if they refer to same address.

You can implement IEqualityComparer<T> and send it as a parameter to Except() function. Here's a blog post you may find helpful.

edit: the original blog post link was broken and has been replaced above

LINQ Except not working as expected

Linq's Except compares objects by their Equals(). You need to override Contacto's Equals and GetHashCode.

Many previous questions explain how:

  • What's the best strategy for Equals and GetHashCode?
  • What is the best algorithm for an overridden System.Object.GetHashCode?

Except also has an overload that recieves an IEqualityComparer if you prefer to implement one instead of overriding the functions

For specifying a comparer inline look at:

  • Can I specify my explicit type comparator inline?

LINQ Except() Method Does Not Work

Since class is a reference type, your ItemsDTO class must override Equals and GetHashCode for that to work.

List.Except is not working

In order to make Except method working as expected, the class AssignUserViewModel must have GetHashCode and Equals methods correctly overridden.

For example, if AssignUserViewModel objects are uniquely defined by their Id, you should define the class in this way:

class AssignUserViewModel
{
// other methods...

public override int GetHashCode()
{
return this.Id.GetHashCode();
}
public override bool Equals(object obj)
{
if (!(obj is AssignUserViewModel))
throw new ArgumentException("obj is not an AssignUserViewModel");
var usr = obj as AssignUserViewModel;
if (usr == null)
return false;
return this.Id.Equals(usr.Id);
}
}

Otherwise, if you can't/don't want to change the class implementation, you can implement an IEqualityComparer<> and pass it to the Except method, e.g. :

class AssignUserViewModelEqualityComparer : IEqualityComparer<AssignUserViewModel>
{
public bool Equals(AssignUserViewModel x, AssignUserViewModel y)
{
if (object.ReferenceEquals(x, y))
return true;
if(x == null || y == null)
return false;
return x.Id.Equals(y.Id);
}

public int GetHashCode(AssignUserViewModel obj)
{
return obj.Id.GetHashCode();
}
}

then your last line would become:

assignUsers = assignUsers.Except(assignedUsers, new AssignUserViewModelEqualityComparer()).ToList();

The method Except in List does not give the right information in C#

Well, you somehow know how to compare two classes, you mentioned:

You understood it wrong _manualReadTagList has 1,2,3,4,5,6 and mrt has 2,4 so I should just get 1,3,5,6

Where are these numbers coming from??? I guess it is the field Tag_Number in ManualReadTag class (if it's different, just replace the field in the code below and it'll work). So you need following code:

_manualReadTagList
.Where(m => !mrt.Select(i => i.Tag_Number).Contains(m.Tag_Number))
.ToList();

Other way would be to override Equals method in ManualReadTag to check equality of instances based on particular field (I assume Tag_Number).

c# Linq Except Not Returning List of Different Values

The problem is here:

IEnumerable<string> x = etaNotifications.OfType<string>();

but etaNotifications is a List<EtaNotificationUser>, none of which can be a string since string is sealed. OfType returns all instances that are of the given type - it does not "convert" each member to that type.

So x will always be empty.

Maybe you want:

IEnumerable<string> x = etaNotifications.Select(e => e.ToString());

if EtaNotificationUser has overridden ToString to give you the value you want to compare. If the value you want to compare is in a property you can use:

IEnumerable<string> x = etaNotifications.Select(e => e.EmailAddress);

or some other property.

You'll likely have to do something similar for y (unless EmailList is already a List<string> which I doubt).

LINQ Except not returning string values correctly

I'm not sure if my assumptions are correct, but it looks like the format of the file generated is two lines per directory entry and that the first line is the full path to the file and hence must be unique.

If that is correct, then the second list can not contain the line TestHash\testFile3.csv.

If so then you can group the directory entry with the permission and then use except to check for differences.

To do this, I first add a line number to each line and then group by every two lines and the create an anonymous object with the first and second entries in each group,

eg

var groupedList1 = list1
.Select((val , index) => new { val, index })
.GroupBy(g => g.index / 2)
.Select(r => r.ToArray())
.Select(r => new { DirectoryEntry = r[0].val , OldPermission = r[1].val , NewPermission = ""}) ;

Because the DirectoryEntry Name is unique, we know that each entry in our grouped list must be unique and hence the except operator will operator as you want.

Or you could combine groupedList1 and groupedList2 like

var allEntries = groupedList1.Select(a=>a.DirectoryEntry).Union(
groupedList2.Select(a=>a.DirectoryEntry));

var combined = (from r in allEntries select new
{
DirectoryEntry = r ,
OldPermission = groupedList1.SingleOrDefault(a=>a.DirectoryEntry == r)?.Permission ,
NewPermission = groupedList2.SingleOrDefault(a=>a.DirectoryEntry == r)?.Permission
}
)
.Where(a=>a.OldPermission != a.NewPermission);

Linq Except not functioning as expected - duplicate items

In this case the problem was actually demonstrated more clearly with a Where clause instead. The actual problem was due to the PrimaryKey being applied on an Entity, rather than a simple field. See Where returns wrong record for more details

Except() and Intersect() doesn't work correctly - LINQ

You need to implement an equality comparer for objects

This has been answered before here
Using Linq Except not Working as I Thought

Please see the blog post below from MSDN for further explanation
http://blogs.msdn.com/b/csharpfaq/archive/2009/03/25/how-to-use-linq-methods-to-compare-objects-of-custom-types.aspx

If you are anonymous types it will work differently without an equality comparer. Here is an example code

http://odetocode.com/blogs/scott/archive/2008/03/25/and-equality-for-all-anonymous-types.aspx



Related Topics



Leave a reply



Submit