Can't really understand how the select extension method works with a list inside another list, like this:
var queries = (from item in list
from item2 in list.anotherlist
select item2).ToList<MyType>();
This will not work:
// Gives me a list of List<QueryResult>
var queries = list.Select(item => item.anotherlist).ToList();
The SelectMany operator ought to do the trick - in this case, it takes a list of lists and flattens it:
var queries = list.SelectMany(sublist => sublist).ToList();
use selectmany
var queries = list.SelectMany(l => l.anotherList).ToList();
Related
I am trying to list all elements from the first list where it contains a substring equal to all elements from the second list
First list:
C:\Folder\Files_01026666.pdf
C:\Folder\Files_01027777.pdf
C:\Folder\Files_01028888.pdf
C:\Folder\Files_01029999.pdf
Second list:
01027777
01028888
List result should be:
C:\Folder\Files_01027777.pdf
C:\Folder\Files_01028888.pdf
the closer that I got was with .Intersect() but both string-element should be equals
List<string> resultList = firstList.Select(i => i.ToString()).Intersect(secondList).ToList();
List<string> resultList = firstList.Where(x => x.Contains(secondList.Select(i=>i).ToString()));
List<string> resultList = firstList.Where(x => x == secondList.Select(i=>i).ToString());
I know I can do this another way but I'd like to do it with LINQ.
I have looked at other queries but I can find a close comparison to this with Linq. Any ideas or anywhere you can point me to would be a great help.
We can use EndsWith() with Path.GetFileNameWithoutExtension(), as strings in the secondList are not entire file names.
var result = firstList
.Where(path => secondList.Any(fileName => Path.GetFileNameWithoutExtension(path).EndsWith(fileName)));
Try Online
var q = list1.Where(t=>Regex.IsMatch(t,String.Join("|",list2.ToArray()))));
Seems to work for lists of strings. Using Regex can be problem in LINQ. This won't work in Linq2SQL for example.
My sample data coloumn, which come from an CSV file is
|----Category------------|
SHOES
SHOES~SHOCKS
SHOES~SHOCKS~ULTRA SOCKS
I would love to split the specific column and get the distinct values in a list like
SHOES
SHOCKS
ULTRA SOCKS
I tried the following, but it does not work as expected.
var test = from c in products select c.Category.Split('~').Distinct().ToList();
It actually returns the following.
Any thoughts please? Thank you.
I would use SelectMany to "flatten" the list before removing duplicates:
products.SelectMany(c => c.Category.Split('~'))
.Distinct()
You can use SelectMany to flatten the collection:
products.SelectMany(p => p.Category.Split('~')).Distinct().ToList();
You were close, you just needed to flatten out your collection to pull the individual items of each grouping via a SelectMany() call :
// The SelectMany will map the results of each of your Split() calls
// into a single collection (instead of multiple)
var test = products.SelectMany(p => p.Category.Split('~'))
.Distinct()
.ToList();
You can see a complete working example demonstrated here and seen below :
// Example input
var input = new string[] { "SHOES","SHOES~SHOCKS","SHOES~SHOCKS~ULTRA SOCKS" };
// Get your results (yields ["SHOES","SHOCKS","ULTRA SOCKS"])
var output = input.SelectMany(p => p.Split('~'))
.Distinct()
.ToList();
Merge this list of list of strings into a single list by using SelectMany() and Just add another Distinct to your List..
var test = from c in products select c.Category.Split('~').Distinct().ToList().SelectMany(x => x).Distinct().ToList();
Here's how you'd do it in query syntax.
var test = (from p in products
from item in p.Category.Split('~')
select item).Distinct().ToList();
I have a query as follows:
var paymentInfo =
from i in dbconnect.tblPayments
where i.tenderId == _tenderId
select i;
This query has some results, but I need to add an additional result that I already have, from the variable PaymentInfo.
For example suppose that my query has 2 results i need to add another result to "PaymentInfo" using linq.
I thought that the result is a kind of list, and that I could call .Add(PaymentInfo), but this doesn't work
How can I do this?
You can use Concat to concat another sequence to the end of this one.
var paymentInfo = paymentInfo.Concat(someOtherPayments);
I thought that the result is a kind of list
No, the result is an IEnumerable<T> which is read-only. You can create a list by calling .ToList() and then add an item to it.
var paymentInfo = (from i in dbconnect.tblPayments
where i.tenderId == _tenderId
select i).ToList();
paymentInfo.Add(existingPayment);
I have a Dictionary in C#:
Dictionary<string, List<string>>
How can I use Linq to flatten this into one List<string> that contains all of the lists in the Dictionary?
Thanks!
Very easily:
var list = dictionary.Values // To get just the List<string>s
.SelectMany(x => x) // Flatten
.ToList(); // Listify
Here the SelectMany call takes a sequence of inputs (the lists which make the values of the dictionary) and projects each single input into another sequence of outputs - in this case "the elements of the list". It then flattens that sequence of sequences into a single sequence.
as a query
var flattened = from p in dictionary
from s in p.Value
select s;
or as methods...
var flattened = dictionary.SelectMany(p => p.Value);
I like this over what others have done as I'm passing the whole dictionary into the Linq query rather than just the values.
SelectMany is the easiest way to flatten things:
Dictionary.Values.SelectMany(x => x).ToList()
Assuming you have an instance called dict:
dict.SelectMany(pair => pair.Value.Select(str => str));
You should try something like this:
dict.Values.Aggregate(new List<String>(), (a, b) => a.Concat(b));
Suppose I have a collection of strings.
How do I select all the elements that don't contain a certain parameter value?
List<string> TheList = .....
var TheCleanList = (from s in TheList
where s != parameter
select s).ToList();
I was thinking about where s!= parameter but I'm wondering if there's a cleaner way to do it.
Thanks.
If you don't need a new list you don't need Linq for this - use Remove()- this avoids having to create a new list:
If you want to remove all strings that are equal to Parameter:
TheList.RemoveAll(s => s == Parameter);
If you want to remove all strings that contain Parameter (not clear from your question):
TheList.RemoveAll(s => s.Contains(Parameter));
You mean:
List<string> TheList = .....
var TheCleanList = (from s in TheList
where !s.Contains(parameter)
select s).ToList();
You can use String.Contains
var TheCleanList = (from s in TheList
where !s.Contains(parameter)
select s).ToList();
Or
var TheCleanList = TheList.Where(s => !s.Contains(parameter)).ToList();
String.Contains is case-sensitive. If you want a case-insensitve:
string lower = parameter.ToLower();
...
where s.ToLower().Contains(lower)