Comparing two lists and deleting identical results c# - c#

I have two lists:
List<int> positionsThatCannotBeMovedTo =...
List<int> desiredLocations =...
I am trying to remove all of the positions which cannot be moved to from the desired locations to create a list of safe positions:
List<int> safePositions = new List<int>(uniquePositions);
safePositions.RemoveAll(positionsThatCannotBeMovedTo);
however it's throwing the error:
"Argument1: cannot convert from 'System.Collections.Generic.List' to 'System.Predicate'
I'm not entirely sure what this means or how I'm misusing the function. Is anybody able to explain this for me please? I am doing it this way because of the answer in this question:
Compare two lists for updates, deletions and additions

RemoveAll takes a Predicate<T>, but you are passing a list:
safePositions.RemoveAll(x => positionsThatCannotBeMovedTo.Contains(x));

There is another way to obtain a list with elements except the elements of another list
List<int> positionsThatCannotBeMovedTo = new List<int>() {1,2,3,4,5,6,7};
List<int> uniquePositions = new List<int>() {5,6,7,8,9,10};
List<int> safePosition = uniquePositions.Except(positionsThatCannotBeMovedTo).ToList();
MSDN on Enumerable<T>.Except

You could also accomplish this using the Except extension method. Assuming uniquePositions is your list of all your positions.
var safePositions = uniquePositions.Except(positionsThatCannotBeMovedTo).ToList();
Except is the set difference operator and as you are using lists of ints the default comparer is fine.

Related

Is there a Linq method to 'extend' collection?

I wonder if there is a Linq method to simply enumerate over another collection after the current one? If not, why not?
To highlight exactly what I mean, imagine we had:
List<int> a = new List<int> { 1, 2, 3 };
int[] b = { 1, 5, 6 };
then I am asking if there is a Linq method such that a.MyHypotheticalExtensionMethod(b) would produce the IEnumerable containing: {1,2,3,1,5,6}
Of course, its trivial to roll one's own (or even to just work around) but it definately seems like something that ought to be included in Linq?
You're looking for a.Concat(b).

refresh array element

i am using array control in which i am saving value one by one.
now i have to delet one of the element and refresh it simultaneuosly.
for example....
string[] arr= new string(25);
arr[0]="A";
arr[1]="B";
arr[2]="C"; and so on....
now after deleting second element via arr[1]=null;
i want refreshed array like mentioned below...
arr[0]="A";
arr[1]="C"; and so on....
please help...
thanks in advance,,,
It sounds like you should be using a List<string> rather than an array, this would give exactly the functionality you are describing.
Although arrays can be resized (thanks #Austin Brunkhorst), this is not "cheap" and you would you would need to move everything around yourself.
It should be noted, that with lots of inserts and removes Lists can get very inefficient, so you'd be better off with a LinkedList<string>. These have advantages and disadvantages. Google linked list for more info.
When you have a static data amount you should use Array, BUT when you have dinamic data amount you should use List<>.
If you want to resize arrays, you have to create a new and copy all elements from the old to the new one.
arr = arr.Where(s => s != null).ToArray();
If you would use a List<string> you could use methods like List.Remove or List.RemoveAt.
If you'll be adding/deleting entries at arbitrary positions in your collection a lot, you'd be better off using a LinkedList<string> instead
Instead of Array you can go with List
List<int> list = new List<int>();
list.Add(2);
list.Add(3);
list.Add(5);
list.Add(7);
you will get more options like
Contains
Exists
IndexOf
For Removing the items you will get the functions like
Remove
ex: dogs.Remove("bulldog"); // Remove bulldog
RemoveAt
ex: list.RemoveAt(1);
RemoveAll

Get certain item from each Tuple from List

What is the correct way to go about creating a list of, say, the first item of each Tuple in a List of Tuples?
If I have a List<Tuple<string,string>>, how would I get a List<string> of the first string in each Tuple?
A little Linq will do the trick:
var myStringList = myTupleList.Select(t=>t.Item1).ToList();
As an explanation, since Tim posted pretty much the same answer, Select() creates a 1:1 "projection"; it takes each input element of the Enumerable, and for each of them it evaluates the lambda expression and returns the result as an element of a new Enumerable having the same number of elements. ToList() will then spin through the Enumerable produced by Select(), and add each element one at a time to a new List<T> instance.
Tim has a good point on the memory-efficiency; ToList() will create a list and add the elements one at a time, which will cause the List to keep resizing its underlying array, doubling it each time to ensure it has the proper capacity. For a big list, that could cause OutOfMemoryExceptions, and it will cause the CLR to allocate more memory than necessary to the List unless the number of elements happens to be a power of 2.
List<string> list = tuples.Select(t => t.Item1).ToList();
or, potentially less memory expensive:
List<string> list = new List<String>(tuples.Count);
list.AddRange(tuples.Select(t => t.Item1));
because it avoids the doubling algorithm of List.Add in ToList.
If you have a List<Tuple<string, string>> listoftuples, you can use the List's implementation of the Select method to take the first string from each Tuple.
It would look like this:
List<string> firstelements = listoftuples.Select(t => t.Item1).ToList();
Generialised Variant:
for selecting a particular item where the collection's tuple's length is unknown i.e 2,3,4 ...:
static IEnumerable TupleListSelectQuery<T>(IEnumerable<T> lst, int index) where T : IStructuralEquatable, IStructuralComparable, IComparable
{
return lst.Select(t => typeof(T).GetProperty("Item" + Convert.ToString(itemNumber)).GetValue(t)).ToList();
}
where index's value corresponds to the way tuples are enumerated i.e 1,2,3 ... (not 0,1,2...).

Best way to compare two large string lists, using C# and LINQ?

I have a large list (~ 110,000 strings), which I need to compare to a similar sized list.
List A comes from 1 system.
List B comes from a SQL table (I can only read, no stored procs, etc)
What is the best way to find what values are in list A, that no longer exists in list B?
Is 100,000 strings a large number to be handled in an array?
thanks
So you have two lists like so:
List<string> listA;
List<string> listB;
Then use Enumerable.Except:
List<string> except = listA.Except(listB).ToList();
Note that if you want to, say, ignore case:
List<string> except = listA.Except(listB, StringComparer.OrdinalIgnoreCase).ToList();
You can replace the last parameter with an IEqualityComparer<string> of your choosing.
With LINQ:
var missing = listA.Except(listB).ToList();
Out of interest, do you HAVE to use List<string>? Because in .net 3.5 SP1, you can use the HashSet and it's ExceptWith method. To my understanding, HashSets are specifically optimized for comparisons between two Sets.
List<string> A = //get from file
List<string> B = //get from db
var C = A.Except(B);
Stealing from this question, it looks like you could use the Except<T>() method.

c# List manipulation

If I have
List<String> text
how can I create a sub-list of all continious elements within a specific range e.g.
List<String> subList = /* all elements within text bar the first 2*/
Also are there any other useful List manipulation tips & tricks that might be useful?
This will work even without LINQ:
List<String> subList = text.GetRange(2, text.Count - 2);
Edit: Fixed a typo.
subList = text.Skip(2).ToList()
Skip(n) returns an IEnumerable<> with all elements except the first n.
When you really need a list after that, ToList() converts it back.
If you're on 3.5, then there are a lot of new and interesting methods available on List. Just check out the section 'Extension methods' here: http://msdn.microsoft.com/en-us/library/d9hw1as6.aspx

Categories