Is there a simple lambda expression to extract elements from one list and put them into another? without LINQ?
for example to map, a source list of elements T to another list (or return a list) with the string name for each element in the source.
Update...with pseudocode.
List<int> intList = new List<int>() { 1, 2, 3};
List<string> stringList = new List<string>(intList.ToArray((i) => intList[i].ToString())); // this doesn't work obviously
stringList should be {"1", "2", "3"}
List<T>.ConvertAll() provides a straightforward way to change types without LINQ.
In your case...
List<string> stringList = intList.ConvertAll(i => i.ToString());
Related
My idea is to use a new list (List1) and compare it with another list (List2) and create a new list (List3) that exclude all common elements in both lists and results on the non common elements. The difficult thing (to me) is that List1 and List2 elements are not a true match. List1 elements might be part of List2 elements, but not a truly match. Using exclude does not seem to allow the use of IndexOf to compare the two list elements.
Does anyone have an idea how to achieve this?
Thanks in advance.
Assuming you have List1 and List2. Below is the simplest way to compare elements in two lists.
IList<string> List3 = new List<string>();
foreach (var item1 in List1)
{
foreach(var item2 in List3)
{
if (item1 == item2)
{
List3.Add(item1);
}
}
}
My idea is to use a new list (List1) and compare it with another list
(List2) and create a new list (List3) that exclude all common elements
in both lists and results on the non common elements.
From Comments
I need to compare each element in both lists List1 element exists in
List2 element (both strings).
One of the easiest ways to find unique from two lists
var List1 = new List<string>() { "a", "b", "c", "d" };
var List2 = new List<string>() { "a", "e", "f", "g", "c","z" };
var List3 = new List<string>();
List3.AddRange(List1.Except(List2));
List3.AddRange(List2.Except(List1));
List3.ForEach(l=>Console.WriteLine(l));
How about this:
List commonElements = new List<string>();
foreach (var smallString in SmallList)
{
if (large.Any(x => x.Contains(smallString)))
{
// Add to common elements
commonElements.Add(smallString);
}
}
I am writing a program where I need to swap values from nested list.
Here is what I am looking for example:
Let's say I have a List<object[]> where these list contains two rows as below:
{"id1", "id2", "id3"}, {1,2,3}
Now I want to make it like below:
{"id1", 1}, {"id2", 2}, {"id3", 3}
How can I do that in C#?
Hopefully I have cleared my point.
With 2 input sequences, this can be treated as a "zip" operation:
List<object[]> list = new List<object[]>
{
new object[] {"id1", "id2", "id3" },
new object[] {1,2,3},
};
var rotated = Enumerable.Zip(list[0], list[1],
(x, y) => new object[] { x, y }).ToList();
Note I would advise against using lots of object[] etc here. There's almost always a better way to represent the data.
With an arbitrary number of input sequences, this would need to be done as a "transpose" operation.
How do I check whether a List contains an element that exists in another List using LINQ in C#? I don't want to use a for/while loop.
So, if List1 has A, B, C and List2 has B, 1, 2, then I would return true.
Try this:
List<string> a = ...
List<string> b = ...
var inComon = a.Intersect(b).Any();
Use Enumerable.Any Method:
List<string> l1 = new List<string> { "1", "2" };
List<string> l2 = new List<string> { "1", "3" };
var result = l2.Any(s => l1.Contains(s));
I'd say the Intersect method (see answer by dasblinkenlight) + Any must work better than Contains + Any. It is definetely better to use Any than Count.
I have two lists
List<string> list1 as new List<string>();
and
List<string> list2 as new List<string>();
What I want to do is create a third list that is a list of differences.
Example:
list1 contains (Test1, Test2, Test3, Test4)
list2 contains (Test1, Test3)
I would want my new list to contain (Test 2, Test4)
I tried using
newlist = list1.Except(list2).ToList();
and for the above example it works fine.
Example 2:
list 1 contains (Test1, Test1, Test2, Test2)
list 2 is empty
I want my newlist to contain everything (Test1, Test1, Test2, Test2)
If I use the same Except method I was using above I get in my newlist (Test1, Test2)
Is there a way I can include the duplicates?
One more final example so it is hopefully clear on what I am looking for
list1 contains (Test1, Test2, Test2, Test3, Test4)
list2 contains (Test1, Test2, Test5, Test6)
I would want my newlist to contain (Test2, Test3, Test4, Test5, Test6)
One more thing is that list1 and list2 are in no particular order and newlist does not need to be in any particular order either.
I think getting what you are looking for here is going to be really hard to do with an out of the box. Really what you need to do is "summarize" both lists something like a count of each item, then from there, do a different on items, THEN a difference on counts.
You'll have to write this one yourself. The way Except probably works is by putting all of the elements from the first collection into the equivalent of aHashSet<T> and removing every item that's in the second.
What I'd do is something similar: put everything from the first collection into aDictionary<T, int> with values corresponding to occurrence counts. Enumerating over the second collection, subtract from these counts. Then reconstruct a list from the updated counts after subtraction.
Does that make sense?
UPDATE: I have compressed my previous code into something a little smaller:
var list1 = new List<string>() { "Test1", "Test2", "Test2", "Test3", "Test4" };
var list2 = new List<string>() { "Test1", "Test2", "Test5", "Test6" };
var newlist = new List<string>();
list1.ForEach(delegate(string s) { if (!list2.Remove(s)) newlist.Add(s); });
newlist = newlist.Concat(list2).ToList();
I have two arrays, x and y, where y is the value of the tens of every element in x. Now, I want to sort y. But, the order of y will be different of x's. So, I can't tell after sorting which element in y was related to, for instance, x[0].
I want a "double sorting" maybe.
Array.Sort has an overload that accepts two arrays; one for the keys, and one for the items. The items of both are sorted according to the keys array:
int[] keys = { 1, 4, 3, 2, 5 };
string[] items = { "abc", "def", "ghi", "jkl", "mno" };
Array.Sort(keys, items);
foreach (int key in keys) {
Console.WriteLine(key); // 1, 2, 3, 4, 5
}
foreach (string item in items) {
Console.WriteLine(item); // abc, jkl, ghi, def, mno
}
So in your case, it sounds like you want:
Array.Sort(y,x); // or Sort(x,y); - it isn't 100% clear
How about?
var selectedArr = new int[] { 1, 3, 5, 7, 9 };
var unorderArr = new int[] { 9, 7, 5, 3, 1 };
var orderedArr = unorderArr.OrderBy(o => selectedArr.IndexOf(o));
If we have two arrays of complex objects and want to sort them according to one of the two arrays then we can use the next approach:
// We want to sort "people" array by "Name" and
// accordingly to it reorder "countries" array.
Person[] people = new Person[]
{
new Person {Name = "Fill"},
new Person {Name = "Will"},
new Person {Name = "Bill"},
};
Country[] countries = new Country[]
{
new Country {Name = "Canada"},
new Country {Name = "UK"},
new Country {Name = "USA"}
};
// Here we sort "people" array, but together with each "Person"
// in sorted array we store its "index" in unsorted array. Then we
// will use this "index" to reorder items in "countries" array.
var sorted = people
.Select((person, index) => new {person, index})
.OrderBy(x => x.person.Name)
.ToArray();
// Here "people" array is sorted by "Name", and
// "contries" array is reordered accordingly to it.
people = sorted.Select(x => x.person).ToArray();
countries = sorted.Select(x => countries[x.index]).ToArray();
Another approach is to use overload of the method Array.Sort with IComparer. At first we should implement IComparer:
private class PeopleComparer : IComparer<Person>
{
public int Compare(Person x, Person y)
{
return x.Name.CompareTo(y.Name);
}
}
And then we can sort two our arrays:
Array.Sort(people, countries, new PeopleComparer());
Here is complete sample that demonstrates these two approaches.
If y is always the tens value of x, y probably shouldn't exist - you should probably just calculate it's value directly off of x when needed.
In general, sorting parallel arrays is only possible (without hand rolling a sort algorithm) when the sort algorithm takes a custom "swap" function, which you can implement in terms of swapping elements in both arrays simultaneously. std::sort in C++ and qsort in C don't allow this.
Also in the general case, consider a single array where the element is a pair of items, rather than a parallel array for each item. This makes using "standard" algorithms easier.