Find elements which aren't in other list [duplicate] - c#

This question already has answers here:
Compare the difference between two list<string>
(3 answers)
Closed 8 years ago.
I am trying to find values of string which aren't includes into other list.
I have list like:
var list1 = new List<string>();
list1.Add("element1");
list1.Add("element2");
var list2 = new List<string>();
list2.Add("element1");
list2.Add("element2");
list2.Add("element3");
I need to find elements from list2 which aren't in list1, so the result should be only:element3. I tried to do something like right join with LINQ, but it was unsuccessful. Maybe someone know proper solution for this?

Use Enumerable.Except
Produces the set difference of two sequences by using the default
equality comparer to compare values.
var result = list2.Except(list1);
Another way of doing that could be:
var result = list2.Where(r => !list1.Contains(r));
If you need a List<string> as result, then just add ToList().

list1.Except(list2)
Returns the set difference between 2 IEnumerables: MSDN

Use Except
var list3 = list2.Except(list1);

list2.Except(List1)
.Except() should work

Related

Find elements from collection contains names from string array [duplicate]

This question already has answers here:
Linq Select All Items Matching Array
(2 answers)
Linq filter List<string> where it contains a string value from another List<string>
(4 answers)
Closed 4 years ago.
How can I create LINQ expression to find elements from collection contains names from string array?
string[] names = ["John", "Hanna", "Bill", "Donald"];
I've created expression like below but it is not correct. How can I fix that?
result = (x => x.CompanyEmployeeName.Contains(names));
If you want check if names contains x.CompanyEmployeeName, you'll want to use:
result = something.Where(x => names.Contains(x.CompanyEmployeeName));
let myCollection be the collection of a custom class having a property Name. you have to get all objects from that collection based on the condition that object's name should be available in the names array. Then You can try this:
var filteredItems = myCollection.Where(x=> names.Any(y=>y == x.Name));
I have added a working example here
In your LINQ, you should have a collection first.
Ex: if you have a list: listCompanyEmployee then you can use bellow expression:
var result = listCompanyEmployee.Where(x => names.Contains(x.CompanyEmployeeName));
You need to reverse it. Check if the names contains the employee
var result = db.CompanyEmployee.Where(x => names.Contains(x.CompanyEmployeeName));
One other option, which is prefered if the list in context are larger then your sample data, is to use Join
var result = db.CompanyEmployee.Join(names, x=> x.CompanyEmployeeName, n => n, (x,n)=> n);
You can use Array.Exists. Example if you want to check if names contains CompanyEmployeeName:
result = something.Where(x => Array.Exists(names, name => name == x.CompanyEmployeeName));
and you can use Array.IndexOf like:
result = something.Where(x => Array.IndexOf(names, x.CompanyEmployeeName) != -1);

Can be avoided redundancy in OrderBy query on a list of simple value types? [duplicate]

This question already has answers here:
LINQ identity function
(7 answers)
Closed 6 years ago.
I am curious to know if there is some method which does not require a lambda operator or not even a parameter to project the elements of a simple value types list. By example in the following case:
var unorderedList = new List<int>{ 3, 1, 2 };
var orderedList = unorderedList.OrderBy(x => x);
The x => x looks a little redundant to me since an int does not have any members to order by, as a more complex object would have. So is there any other method (preferably in Linq) that returns an ordered list whitout taking an extra parameter?
Just something as : var orderedList = unorderedList.Order();
If you're ok stepping out of the LINQ world, since you've got a List<int>, you can use the built-in Sort method:
var unorderedList = new List<int> { 3, 1, 2 };
var orderedList = new List<int>(unorderedList);
orderedList.Sort();
Maybe own OrderBy as extension method?
public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> source) => source.OrderBy(x => x);
C# 6.0 syntax used.

Linq Contains without considering accents [duplicate]

This question already has an answer here:
Complex "Contains" string comparison
(1 answer)
Closed 7 years ago.
I need to get all the results where the text contains a particular word ignoring all accents.
Now I have the following:
filtered = result.Where(p => p.#string.ToString().ToUpper().Contains(word));
Or a simplified version:
filtered = result.ToUpper().Contains(word));
How can I make the "Contains" statement ignore the accents?
Thanks in advance
Borrowing a similar solution form here:
string[] result = {"hello there", "héllo there","goodbye"};
string word = "héllo";
var compareInfo = CultureInfo.InvariantCulture.CompareInfo;
var filtered = result.Where(
p => compareInfo.IndexOf(p, word, CompareOptions.IgnoreNonSpace) > -1);
You want to use the StringComparison.InvariantCultureIgnoreCase enum.
Source https://msdn.microsoft.com/en-us/library/system.stringcomparison(v=vs.110).aspx
filtered = result.Contains(word, StringComparison.InvariantCultureIgnoreCase);
However this is only going to work with LinqToObject. If you are using LinqToSQL or LinqToEntityFramework or LinqToNHibernate, this will not work.

How to find the difference between 2 IEnumerable objects

I have 2 list of guids as:
IEnumerable<dynamic> userids = null;
IEnumerable<dynamic> lsCheckedUsers = null;
The userids and lsCheckedUsers list are populated from a SQL database using dapper.
I now wish to find all userids that are not in lsCheckedUsers.
I have tried the following
var userdifference = userids.Where(i => !lsCheckedUsers.Contains(lsCheckedUsers));
var userdifference = userids.Except(lsCheckedUsers);
None of the above actual returns the difference between the 2.
How do I get the difference of guids that do not exist in both.
I am certain that lsCheckedUsers has Guids that are in userids
This is correct:
var userdifference = userids.Except(lsCheckedUsers);
It will work if both of your IEnumerable<dynamic> actually contain Guids. Print out or inspect the items in each to make sure they are Guids.
You should really be using IEnumerable<Guid> and cast the incoming items to Guids if this is what you are expecting. It will hopefully prevent errors like the one you are potentially seeing.
Something along those lines..
var difference = list1.Where (e => !list2.Any(a => a == e))
You have:
var userdifference = userids.Where(i => !lsCheckedUsers.Contains(lsCheckedUsers));
But I think you mean:
var userdifference = userids.Where(i => !lsCheckedUsers.Contains(i));
Update:
To everyone marking down these answers because of "reference" comparisons, consider that Guid is a value type so its equality is evaluated differently. Try this simple test to convince yourself:
var guid = Guid.NewGuid();
var guids = new[] { new Guid(guid.ToString()) };
Console.WriteLine(guids.Contains(guid));
You'll see that the result is True.
Enumerable has an Except method
Enumerable.Except Method (IEnumerable, IEnumerable)
And use String or GUID.
It will compare values for equals.
HashSet ExceptWith would probably have better performance.
But cannot use HashSet if you need to allow duplicates.
HashSet.ExceptWith Method

Remove elements from one List<T> that are found in another

I have two lists
List<T> list1 = new List<T>();
List<T> list2 = new List<T>();
I want remove all elements from list1, which also exist in list2. Of course I can loop through the first loop looking for each element in list2, but I am looking for elegant solution.
Thanks!
To change the actual list1 in place, you could use
list1.RemoveAll(item => list2.Contains(item));
You might instead prefer to simply have a query over the lists without modifying either
var result = list1.Except(list2);
LukeH makes a good recommendation in the comments. In the first version, and if list2 is particularly large, it might be worth it to load the list into a HashSet<T> prior to the RemoveAll invocation. If the list is small, don't worry about it. If you are unsure, test both ways and then you will know.
var theSet = new HashSet<YourType>(list2);
list1.RemoveAll(item => theSet.Contains(item));
With LINQ:
var result = list1.Except(list2);
list1.RemoveAll( item => list2.Contains(item));
Description
I think you mean the generic type List<Type>. You can use Linq to do this
Sample
List<string> l = new List<string>();
List<string> l2 = new List<string>();
l.Add("one");
l.Add("two");
l.Add("three");
l2.Add("one");
l2.Add("two");
l2.Add("three");
l2.Add("four");
l2.RemoveAll(x => l.Contains(x));
More Information
MSDN - List.RemoveAll Method
var result = list1.Except(list2);
Using LINQ you can do this:
List1.RemoveAll(i => !List2.Contains(i));
If you want to remove a list of objects (list2) from another list (list1) use:
list1 = list1.Except(list2).ToList()
Remember to use ToList() to convert IEnumerable<T> to List<T>.
var NewList = FirstList.Where(a => SecondList.Exists(b => b.ID != a.ID));
Using LINQ

Categories

Resources