score:5
not too difficult to do. in your filelist class create a child class that inherits from iequalitycomparer<>
public class filelistcomparer : iequalitycomparer<filelist>
{
public bool equals(filelist x, filelist y)
{
if (x == null || y == null)
{
return false;
}
return x.filenames.equals(y.filenames, stringcomparison.ordinalignorecase);
}
public int gethashcode(filelist obj) { return base.gethashcode(); }
}
and then when you call except, use the comparer
ienumerable<filelist> except = sourcefilenames.except(destinationfilenames, new filelist.filelistcomparer() );
score:0
i think jon skeet's answer is the best answer, but your other option is looking directly into the property you want to compare (filenames)
var destnames = destinationfilenames.select(destname => destname.filenames);
ienumerable<filelist> except = sourcefilenames
.where(sourcename => !destnames.contains(sourcename.filenames));
or (same thing in one expression)
ienumerable<filelist> except = sourcefilenames
.where(sourcename => !destinationfilenames
.select(destnames => destnames.filenames)
.contains(sourcename.filenames));
edit: thanks for the downvote; i tested the code and found a bug. it works now!
score:2
i upvoted masenkablast answer, i think the default equality comparer for class instances defaults to class instances' memory address comparison(not the value in class instance itself), so you have to provide your own value equality comparison.
but if you have simple data structure, try to use struct. i tried your code and changed class filelist
to struct filelist
, it works, it only displays 3 and 4
[edit] if you want to continue using class without implementing the iequalitycomparer, just implement iequatable on your class, idea sourced from http://msdn.microsoft.com/en-us/library/bb300779.aspx
using system;
using system.collections.generic;
using system.linq;
using system.text;
namespace exceptlist
{
class program
{
static void main(string[] args)
{
var sourcefilenames = new list<filelist>();
sourcefilenames.add(new filelist { filenames = "1.txt" });
sourcefilenames.add(new filelist { filenames = "2.txt" });
sourcefilenames.add(new filelist { filenames = "3.txt" });
sourcefilenames.add(new filelist { filenames = "4.txt" });
list<filelist> destinationfilenames = new list<filelist>();
destinationfilenames.add(new filelist { filenames = "1.txt" });
destinationfilenames.add(new filelist { filenames = "2.txt" });
var except = sourcefilenames.except(destinationfilenames);
// list only 3 and 4
foreach (var f in except)
console.writeline(f.filenames);
console.readline();
}
}
class filelist : iequatable<filelist>
{
public string filenames { get; set; }
#region iequatable<filelist> members
public bool equals(filelist other)
{
//check whether the compared object is null.
if (object.referenceequals(other, null)) return false;
//check whether the compared object references the same data.
if (object.referenceequals(this, other)) return true;
return filenames.equals(other.filenames);
}
#endregion
public override int gethashcode()
{
return filenames.gethashcode();
}
}
}
score:8
sourcefilenamelist.except(destinaitonlist)
score:14
that's what except
is for:
var files = sourcefilenamelist.except(destinationlist);
note that this is a set operation, so if the source list has duplicate entries you'll only see unique results: new[] {a, a, b, b, c}.except(new[] {b, c})
is just {a}
, not {a, a}
.
like many linq operators, this returns an ienumerable<t>
- if you want it back as a list
just call tolist
:
var files = sourcefilenamelist.except(destinationlist).tolist();
edit: okay, now you've shown what filelist
is, the problem is simply that you haven't implemented equality comparisons. you can do this either by overriding equals
and gethashcode
(and possibly iequatable<filelist>
) or by implementing iequalitycomparer<t>
. however, you've still got a problem: filenames
is a mutable type, and those don't typically work well in terms of hashing and equality. two instances may be equal initially, and then one of them could change. i'd recommend reimplementing this as an immutable type. something like this:
public sealed class filelist : iequatable<filelist>
{
private readonly string filenames;
public string filenames { get { return filenames; } }
public filelist(string filenames)
{
// if you want to allow a null filenames, you'll need to change
// the code in a few places
if (filenames == null)
{
throw new argumentnullexception("filenames");
}
this.filenames = filenames;
}
public override int gethashcode()
{
return filenames.gethashcode();
}
public override bool equals(object other)
{
return equals(other as filelist);
}
public bool equals(filelist other)
{
return other != null && other.filenames == filenames;
}
}
your sample code could then become:
list<filelist> sourcefilenames = new list<filelist>
{
new filelist("1.txt"),
new filelist("2.txt"),
new filelist("3.txt"),
new filelist("4.txt")
};
list<filelist> destinationfilenames = new list<filelist>
{
new filelist("1.txt"),
new filelist("2.txt")
};
ienumerable<filelist> except = sourcefilenames.except(destinationfilenames);
Source: stackoverflow.com
Related Query
- Where Not In OR Except simulation of SQL in LINQ to Objects
- LINQ query Where ID does not exist as a property in a list of objects
- Dynamic Linq to SQL - Where Not Like
- Linq to Sql isnull in where clause not working
- SQL to LINQ Query with date in where clause is not working
- LINQ to SQL Finding objects not listed in another list
- C# Linq SQL get results where ID not in table
- LINQ with Group, Join and Where Easy in SQL not in LINQ?
- Why will linq to sql not allow a meber with an "override" inheritance modifier in the where clause?
- Get Records from table where quantity is not between fromquantity and ToQuantity using Linq to SQL
- linq to sql not putting quotes around strings in where clause
- EF Core LINQ Where with extension methods are not translated to SQL
- Where Clause is not applied when converting the query from LINQ (EF) to SQL
- Linq select objects in list where exists IN (A,B,C)
- Distinct not working with LINQ to Objects
- What can I do to resolve a "Row not found or changed" Exception in LINQ to SQL on a SQL Server Compact Edition Database?
- LINQ to SQL Where Clause Optional Criteria
- What's your favorite LINQ to Objects operator which is not built-in?
- How are people unit testing code that uses Linq to SQL
- LINQ syntax where string value is not null or empty
- LINQ - Where not exists
- Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator
- Linq where column == (null reference) not the same as column == null
- Using LINQ to Objects to find items in one collection that do not match another
- LINQ To SQL exception: Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains operator
- Linq to Select Parent Objects Where Child Objects Have a Matching Child Object
- C# LINQ select from where value is not contained in array / list
- LINQ query to perform a projection, skipping or wrapping exceptions where source throws on IEnumerable.GetNext()
- Odd behavior in LINQ to SQL with anonymous objects and constant columns
- Using Linq Except not Working as I Thought
More Query from same tag
- How to set up multiple IObservers in a loop
- Order an Array of Rectangles by Size
- LINQ Query on ConcurrentDictionary of 19710 items slow
- LINQ - Adding record where nested value contains value from another array
- Speeding up a linq query
- C# using LINQ to limit a recursive list
- Performance implications of calling ToArray inside a LINQ selector
- What is the Linq.First equivalent in PowerShell?
- Sorting the items of a recursive list with "infinite" levels/generations
- Find and Replace characters in a string based on two arrays in c#
- Accessing Linq data in telerik grid ItemCreated method
- Can I refactor a range variable in a linq statement?
- SQL 'IN' Operator with LINQ in Visual Studio Lightswitch
- How to shift the data in a list
- Is it possible to build a complex query using expression tree
- Filtering duplicates from a type collection using LINQ
- How to pass Expression<Func<int>> to a function
- LINQ many to many Left Join Grouping
- LINQ - Merge two queries and exclude items from the first query
- LINQ query computing vote count
- How do I use LINQ to filter a datatable against a Lst of strings that need to be split?
- .net linq entity framework groupby
- How do I write a Linq query that needs a subquery?
- How to blend an if-else into linq query syntax statement
- Expression parameter is not defined
- What's the meaning of multiple from selectors in a LINQ query
- Unexpected output of LINQ Where when filtering by Contains(variable)
- ValueInjecter - Joins multiple result sets into 1 collection LINQ?
- Joining and grouping multiple tables with LINQ when using a linking table
- Use PHPLinq in codeigniter