I have two separate IEnumerable lists having dynamic values:
First list is IEnumerable<string> SubHeadId having data like
[0]->1
[1]->4
Second list is IEnumerable<string> SubHeadId having data like
[0]->100
[1]->233
I want to join these two lists into single list having data like
[0]->1,100
[1]->4,233
How can I join lists. Please Guide.
Thanks
The proper way to achieve this is using the Zip() extension method:
var firstList = new List<string>() { "1", "4" };
var secondList = new List<string>() { "100", "233" };
var combined = firstList.Zip(secondList, (f, s) => f + ", " + s ).ToList();
It's important to notice here that:
If you happen to have two collections with an unequal number of elements, the Zip method will only continue to the shortest index where both elements exist. No errors will occur if the two collections are uneven.
Related
I have a 2D nested list List<list<dynamic>>, I'd like to get first elements of every second level list and form a new List<dynamic>.
I know .first() gets the first element of a list, but how can I apply it on multiple sub lists?
Thanks in advance.
Proper and efficient way of doing this is as follows:
mainList.Select(subList => subList?.First()).OfType<dynamic>();
This will take care of null lists and null elements
If you want to select all the elements of sublists try following
mainlist.Select(subList => subList).OfType<List<dynamic>>();
This will only take care of null lists
IEnumerable s = listOfLists.Where(lists => lists.Any())
.Select(array => array.First());
Explanation:
First fetch the list of arrays where there are any records by using lists => lists.Any()
Then select the first item from each list and return.
try this please if you want to take the first two elements of each list, and the more elements you want you can increase the integer in the .Take().
List<List<string>> originalList = new List<List<string>>()
{
new List<string>(){"1","1","1"},
new List<string>(){"2","2"},
};
var FirtTwoElementsList = originalList.Select(x => x.Take(2)).ToList();
List<string> FinalList = new List<string>();
foreach (var item in FirtTwoElementsList)
{
FinalList.AddRange(item.ToList<string>());
}
I have data from two data structures that I would like to join with respect to date. Each data structure contains 88 values and every date in one structure has a corresponding date in the other structure. However, when I try to join them, the list with the joined result contains 90 values. In other words the result contains two extra values. When I inspect the values in the joined list it seems that it contains two extra values at the start of the list that are identical to the first "expected" joined value.
Any ideas what might be wrong?
Here is the join expression that I am using:
//Joins vib and RPM with respect to date
var joinedVibRPM = serie.Value.Values.Join(
RPMSeriesOne.Values,
_vib => _vib.DateTime,
_rpm => _rpm.DateTime,
(_vib, _rpm) => new { vib = _vib.Value, rpm = _rpm.Value }).ToList();
You can explain the result when your input sets have duplicate entries. Consider for example this join of two list with four items each (using strings, not DateTime for better readability):
var items1 = new { "A", "B", "C", "C" };
var items2 = new { "A", "B", "B", "C" };
If you perform this join:
var joinedItems =
from item1 in items1
join item2 in items2 on item1 equals item2
select item1 + item2;
Your result will be:
{ "AA", "BB", "BB", "CC", "CC" }
You will find "BB" twice because it is repeated in the secod list and "CC" twice because it is repeated in the first list. In total you will get 5 items.
If you have any duplicate dates in either structure then one element in one structure will match 2 (or more) elements in the other structure. This will give you more than 88 results.
Check your structures for distinct values:
serie.Value.Values.Distinct().Count();
and
RPMSeriesOne.Values.Distinct().Count();
One of these results will likely be less than 88 indicating the presence of duplicates.
Hello I have these two Lists
List<string> list1 = {"404a49ad-d80f-4ef7-99ab-0996de3b70d4_29190_806.jpg|Name1", "404a49ad-d80f-4ef7-99ab-0996de3b70d4_29197_806.jpg|Name2", "404a49ad-d80f-4ef7-99ab-0996de3b70d4_29210_868.jpg|Name3"}
List<string> list2 = {"404a49ad-d80f-4ef7-99ab-0996de3b70d4_29190_806.jpg","404a49ad-d80f-4ef7-99ab-0996de3b70d4_29197_806.jpg"}
I want to intersect the values of list1 separating by '|' character, with the list2 values, but I want to return the full string of list1 and not only the first part separated by '|' character.
This is the result i want:
var finalList = {"404a49ad-d80f-4ef7-99ab-0996de3b70d4_29190_806.jpg|Name1", "404a49ad-d80f-4ef7-99ab-0996de3b70d4_29197_806.jpg|Name2"}
I dont know if its possible with the instersect function or there is another approach I can use. I've tried using Contains function in a predicate but it takes to much time to find the matches.
I'm using large lists with 2000 elements approx.
Thanks!
Try this, gives the expected results in LinqPad, using your example:
var intersection =
list1.Join(
list2,
l1 => l1.Split('|')[0], //Selector for items from the inner list splits on '|'
l2 => l2, //Select the current item
(l1, l2) => l1);
Compile list2 into a HashSet<string> to allow fast lookups. Then, use a simple Where filter to perform lookups of substrings from list1 against this set.
List<string> list1 = new List<string> { "404a49ad-d80f-4ef7-99ab-0996de3b70d4_29190_806.jpg|Name1", "404a49ad-d80f-4ef7-99ab-0996de3b70d4_29197_806.jpg|Name2", "404a49ad-d80f-4ef7-99ab-0996de3b70d4_29210_868.jpg|Name3" };
List<string> list2 = new List<string> { "404a49ad-d80f-4ef7-99ab-0996de3b70d4_29190_806.jpg", "404a49ad-d80f-4ef7-99ab-0996de3b70d4_29197_806.jpg" };
var list2HashSet = new HashSet<string>(list2);
var finalList = list1.Where(s => list2HashSet.Contains(s.Substring(0, s.IndexOf('|')))).ToList();
Note that s.Substring(0, s.IndexOf('|')) is semantically equivalent to s.Split('|')[0] (assuming that all your strings contain |), but avoids the overhead of allocating another string instance for the text behind the |.
Use where to iterate over the list. Use the Split method to get the first part you are interested in, and then check to see if list2 contains that string. Finally call ToList to convert the result to a list.
var finalList = list1.Where(x => list2.Contains(x.Split(new []{'|'})[0})).ToList();
lest say I have two lists
List1:
"Tom",
"Frank",
"Lacey"
List2:
"Frank",
"Tom"
what would be the query needed to show that Tom and Fran are being repeated?
The lists that I am trying to compare are very big and if I do something like:
var q = from a in List1
from b in List2
where a.Name == b.Name
select a;
this takes a long time.
To see what values are duplicated across lists, you can use
var results = list1.Intersect(list2);
If you were otherwise interested in matching the items and doing something with each, you could use Join
var results = from item1 in list1
join item2 in list2
on item1 equals item2
select new
{
// include what you want here
};
In your case, since you are dealing with a list of strings, Intersect seems like the appropriate course of action. If you were dealing with matching lists of objects on a common key, you might opt to join the lists and project the results.
You should use Intersect:
var items = List1.Intersect(List2); // Tom, Frank
You can use intersect:
List<string> list3 = list1.Intersect(list2).ToList();
I'm having a List<List<String>>, and which contains
{ {"A" , "B" },
{"C" , "D" }
}
I need to union all the innerlist into another list
So the resulting List<String> will contain
{"A","B","C","D"}
Now im using for loop to do this
Is there any way to do this Using LINQ or Lambda Expression.
Please help me to do this.
Thanks in advance.
Not Exactly a Union, but you can try this
YourList.SelectMany(l=>l).Distinct()
List<List<string>> collections = new List<List<string>>()
{
new List<string>(){"A" , "B" },
new List<string>() {"C" , "D" }
};
var list = collections.SelectMany(x => x).ToList();
SelectMany builds up a expression tree that when evaluated flattens the list of list to a single list of combined members.
ToList forces the expression tree to be evaluated and which results in a List.
If you want to eliminate duplicates you can add a Distinct call before the call to 'ToList()'
You can use the SelectMany extension method.
List<List<String>> masterList = { {"A" , "B" }, {"C" , "D" } };
IEnumerable<string> results = masterList.SelectMany(l => l);
var result = myLists.SelectMany(l => l);
How about Aggregate?
myLists.Aggregate((left, right) => left.Union(right));
To me, this is more expressive than using SelectMany, because it is telling you exactly what you are doing: Aggregate your list of lists by calling union on them all.
Just for kicks:
(from list in theList from e in list select e).Distinct().ToList()
This is of course the same solution as #Alexander Taran's, just with query syntax instead of lambda syntax. (Or at least it should be – I don't have my LINQPad handy.)