I have a list of strings
List<string> listOfstring = new List<string> { "a", "app", "1", "bam", "man","......."};//a big list
now I need all the strings which start with app in linq
Using the Where function in System.Linq is what you are looking for. We can also use the starts with function to get all values from your list that start with the word "app".
var results = listOfstring.Where(x => x.StartsWith("app", StringComparison.Ordinal)).ToList();
You can do this listOfstring.Where(x => x.StartsWith("app"))
There are two ways to write LINQ:
1. Query Syntax
2. Method Syntax
Using query syntax:
var results = from s in listOfstring where x.StartsWith("app") select s;
Using method syntax:
var results = listOfstring.Where(x=> x.StartsWith("app"));
Hope this helps.
Related
I have a list like so and I want to be able to search within this list for a substring coming from another string. Example:
List<string> list = new List<string>();
string srch = "There";
list.Add("1234 - Hello");
list.Add("4234 - There");
list.Add("2342 - World");
I want to search for "There" within my list and return "4234 - There". I've tried:
var mySearch = list.FindAll(S => s.substring(srch));
foreach(var temp in mySearch)
{
string result = temp;
}
With Linq, just retrieving the first result:
string result = list.FirstOrDefault(s => s.Contains(srch));
To do this w/o Linq (e.g. for earlier .NET version such as .NET 2.0) you can use List<T>'s FindAll method, which in this case would return all items in the list that contain the search term:
var resultList = list.FindAll(delegate(string s) { return s.Contains(srch); });
To return all th entries:
IEnumerable<string> result = list.Where(s => s.Contains(search));
Only the first one:
string result = list.FirstOrDefault(s => s.Contains(search));
What you've written causes the compile error
The best overloaded method match for 'string.Substring(int)' has some invalid arguments
Substring is used to get part of string using character position and/or length of the resultant string.
for example
srch.Substring(1, 3) returns the string "her"
As other have mentioned you should use Contains which tells you if one string occurs within another. If you wanted to know the actual position you'd use IndexOf
same problem i had to do.
You need this:
myList.Where(listStrinEntry => myString.IndexOf(listStringEntry) != -1)
Where:
myList is List<String> has the values
that myString has to contain at any position
So de facto you search if myString contains any of the entries from the list.
Hope this is what you wanted...
i like to use indexOf or contains
someString.IndexOf("this");
someString.Contains("this");
And for CaseSensitive use:
YourObj yourobj = list.FirstOrDefault(obj => obj.SomeString.ToLower().Contains("some substring"));
OR
YourObj yourobj = list.FirstOrDefault(obj => obj.SomeString.ToUpper().Contains("some substring"));
I have a string array and a list and data is like below,
string[] str = new string[2] { "Prod1", "Prod2" };
List<RegistryPathData> data = new List<RegistryPathData>
{
new RegistryPathData{AppName="test1", RegPath="Prod1|Version"},
new RegistryPathData{AppName="test2", RegPath="Prod2|Version"},
new RegistryPathData{AppName="test3", RegPath="Prod3|Version"},
new RegistryPathData{AppName="test4", RegPath="Prod4|Version"},
new RegistryPathData{AppName="test5", RegPath="Prod5|Version"},
};
Now I want to exclude items from List<RegistryPathData> which is NOT matching with string array (prod1 & prod2). Need to exclude below 2, how to do this?
new RegistryPathData{AppName="test1", RegPath="Prod1|Version"},
new RegistryPathData{AppName="test2", RegPath="Prod2|Version"},
Use List.RemoveAll() function like this.
data.RemoveAll(d => str.Contains(d.RegPath.Split('|')[0]));
Use the Where method from LINQ and then check if any of the strings inside the str array match with the RegPath of the current object. Like this:
List<RegistryPathData> dataOnlyProd1And2 = data
.Where(rpd => str.Any(s => rpd.RegPath.StartsWith(s)))
.ToList();
You can use the LINQ .Where() method to filter a sequence of values based on a predicate.
data.Where(d => !str.Contains(d.RegPath.Split('|')[0]));
This means filter out the items in the list where the string up to the first pipe character is not contained in the str array.
I have a list of strings in a List container class that look like the following:
MainMenuItem|MenuItem|subItemX
..
..
..
..
MainMenuItem|MenuItem|subItem99
What I am trying to do is transform the string, using LINQ, so that the first item for each of the tokenised string is removed.
This is the code I already have:
protected static List<string> _menuItems = GetMenuItemsFromXMLFile();
_menuItems.Where(x => x.Contains(menuItemToSearch)).ToList();
First line of code is returning an entire XML file with all the menu items that exist within an application in a tokenised form;
The second line is saying 'get me all menu items that belong to menuItemToSearch'.
menuItemToSearch is contained in the delimited string that is returned. How do I remove it using linq?
EXAMPLE
Before transform: MainMenuItem|MenuItem|subItem99
After transform : MenuItem|subItem99
Hope the example illustrates my intentions
Thanks
You can take a substring from the first position of the pipe symbol '|' to remove the first item from a string, like this:
var str = "MainMenuItem|MenuItem|subItemX";
var dropFirst = str.Substring(str.IndexOf('|')+1);
Demo.
Apply this to all strings from the list in a LINQ Select to produce the desired result:
var res = _menuItems
.Where(x => x.Contains(menuItemToSearch))
.Select(str => str.Substring(str.IndexOf('|')+1))
.ToList();
Maybe sth like this can help you.
var regex = new Regex("[^\\|]+\\|(.+)");
var list = new List<string>(new string[] { "MainMenuItem|MenuItem|subItem99", "MainMenuItem|MenuItem|subItem99" });
var result = list.Where(p => regex.IsMatch(p)).Select(p => regex.Match(p).Groups[1]).ToList();
This should work correctly.
I have a list like so and I want to be able to search within this list for a substring coming from another string. Example:
List<string> list = new List<string>();
string srch = "There";
list.Add("1234 - Hello");
list.Add("4234 - There");
list.Add("2342 - World");
I want to search for "There" within my list and return "4234 - There". I've tried:
var mySearch = list.FindAll(S => s.substring(srch));
foreach(var temp in mySearch)
{
string result = temp;
}
With Linq, just retrieving the first result:
string result = list.FirstOrDefault(s => s.Contains(srch));
To do this w/o Linq (e.g. for earlier .NET version such as .NET 2.0) you can use List<T>'s FindAll method, which in this case would return all items in the list that contain the search term:
var resultList = list.FindAll(delegate(string s) { return s.Contains(srch); });
To return all th entries:
IEnumerable<string> result = list.Where(s => s.Contains(search));
Only the first one:
string result = list.FirstOrDefault(s => s.Contains(search));
What you've written causes the compile error
The best overloaded method match for 'string.Substring(int)' has some invalid arguments
Substring is used to get part of string using character position and/or length of the resultant string.
for example
srch.Substring(1, 3) returns the string "her"
As other have mentioned you should use Contains which tells you if one string occurs within another. If you wanted to know the actual position you'd use IndexOf
same problem i had to do.
You need this:
myList.Where(listStrinEntry => myString.IndexOf(listStringEntry) != -1)
Where:
myList is List<String> has the values
that myString has to contain at any position
So de facto you search if myString contains any of the entries from the list.
Hope this is what you wanted...
i like to use indexOf or contains
someString.IndexOf("this");
someString.Contains("this");
And for CaseSensitive use:
YourObj yourobj = list.FirstOrDefault(obj => obj.SomeString.ToLower().Contains("some substring"));
OR
YourObj yourobj = list.FirstOrDefault(obj => obj.SomeString.ToUpper().Contains("some substring"));
Is it possible to convert two or more lists into one single list, in .NET using C#?
For example,
public static List<Product> GetAllProducts(int categoryId){ .... }
.
.
.
var productCollection1 = GetAllProducts(CategoryId1);
var productCollection2 = GetAllProducts(CategoryId2);
var productCollection3 = GetAllProducts(CategoryId3);
You can use the LINQ Concat and ToList methods:
var allProducts = productCollection1.Concat(productCollection2)
.Concat(productCollection3)
.ToList();
Note that there are more efficient ways to do this - the above will basically loop through all the entries, creating a dynamically sized buffer. As you can predict the size to start with, you don't need this dynamic sizing... so you could use:
var allProducts = new List<Product>(productCollection1.Count +
productCollection2.Count +
productCollection3.Count);
allProducts.AddRange(productCollection1);
allProducts.AddRange(productCollection2);
allProducts.AddRange(productCollection3);
(AddRange is special-cased for ICollection<T> for efficiency.)
I wouldn't take this approach unless you really have to though.
Assuming you want a list containing all of the products for the specified category-Ids, you can treat your query as a projection followed by a flattening operation. There's a LINQ operator that does that: SelectMany.
// implicitly List<Product>
var products = new[] { CategoryId1, CategoryId2, CategoryId3 }
.SelectMany(id => GetAllProducts(id))
.ToList();
In C# 4, you can shorten the SelectMany to: .SelectMany(GetAllProducts)
If you already have lists representing the products for each Id, then what you need is a concatenation, as others point out.
you can combine them using LINQ:
list = list1.Concat(list2).Concat(list3).ToList();
the more traditional approach of using List.AddRange() might be more efficient though.
List.AddRange will change (mutate) an existing list by adding additional elements:
list1.AddRange(list2); // list1 now also has list2's items appended to it.
Alternatively, in modern immutable style, you can project out a new list without changing the existing lists:
Concat, which presents an unordered sequence of list1's items, followed by list2's items:
var concatenated = list1.Concat(list2).ToList();
Not quite the same, Union projects a distinct sequence of items:
var distinct = list1.Union(list2).ToList();
Note that for the 'value type distinct' behaviour of Union to work on reference types, that you will need to define equality comparisons for your classes (or alternatively use the built in comparators of record types).
You could use the Concat extension method:
var result = productCollection1
.Concat(productCollection2)
.Concat(productCollection3)
.ToList();
I know this is an old question I thought I might just add my 2 cents.
If you have a List<Something>[] you can join them using Aggregate
public List<TType> Concat<TType>(params List<TType>[] lists)
{
var result = lists.Aggregate(new List<TType>(), (x, y) => x.Concat(y).ToList());
return result;
}
Hope this helps.
list4 = list1.Concat(list2).Concat(list3).ToList();
// I would make it a little bit more simple
var products = new List<List<product>> {item1, item2, item3 }.SelectMany(id => id).ToList();
This way it is a multi dimensional List and the .SelectMany() will flatten it into a IEnumerable of product then I use the .ToList() method after.
I've already commented it but I still think is a valid option, just test if in your environment is better one solution or the other. In my particular case, using source.ForEach(p => dest.Add(p)) performs better than the classic AddRange but I've not investigated why at the low level.
You can see an example code here: https://gist.github.com/mcliment/4690433
So the option would be:
var allProducts = new List<Product>(productCollection1.Count +
productCollection2.Count +
productCollection3.Count);
productCollection1.ForEach(p => allProducts.Add(p));
productCollection2.ForEach(p => allProducts.Add(p));
productCollection3.ForEach(p => allProducts.Add(p));
Test it to see if it works for you.
Disclaimer: I'm not advocating for this solution, I find Concat the most clear one. I just stated -in my discussion with Jon- that in my machine this case performs better than AddRange, but he says, with far more knowledge than I, that this does not make sense. There's the gist if you want to compare.
To merge or Combine to Lists into a One list.
There is one thing that must be true: the type of both list will be
equal.
For Example: if we have list of string so we can add add another list to the
existing list which have list of type string otherwise we can't.
Example:
class Program
{
static void Main(string[] args)
{
List<string> CustomerList_One = new List<string>
{
"James",
"Scott",
"Mark",
"John",
"Sara",
"Mary",
"William",
"Broad",
"Ben",
"Rich",
"Hack",
"Bob"
};
List<string> CustomerList_Two = new List<string>
{
"Perter",
"Parker",
"Bond",
"been",
"Bilbo",
"Cooper"
};
// Adding all contents of CustomerList_Two to CustomerList_One.
CustomerList_One.AddRange(CustomerList_Two);
// Creating another Listlist and assigning all Contents of CustomerList_One.
List<string> AllCustomers = new List<string>();
foreach (var item in CustomerList_One)
{
AllCustomers.Add(item);
}
// Removing CustomerList_One & CustomerList_Two.
CustomerList_One = null;
CustomerList_Two = null;
// CustomerList_One & CustomerList_Two -- (Garbage Collected)
GC.Collect();
Console.WriteLine("Total No. of Customers : " + AllCustomers.Count());
Console.WriteLine("-------------------------------------------------");
foreach (var customer in AllCustomers)
{
Console.WriteLine("Customer : " + customer);
}
Console.WriteLine("-------------------------------------------------");
}
}
In the special case: "All elements of List1 goes to a new List2": (e.g. a string list)
List<string> list2 = new List<string>(list1);
In this case, list2 is generated with all elements from list1.
You need to use Concat operation
When you got few list but you don't know how many exactly, use this:
listsOfProducts contains few lists filled with objects.
List<Product> productListMerged = new List<Product>();
listsOfProducts.ForEach(q => q.ForEach(e => productListMerged.Add(e)));
If you have an empty list and you want to merge it with a filled list, do not use Concat, use AddRange instead.
List<MyT> finalList = new ();
List<MyT> list = new List<MyT>() { a = 1, b = 2, c = 3 };
finalList.AddRange(list);