how to match string in a list - linq

I'm having a list of string like
var target = new List<string>() { "C", "C-sharp", "java" };
I'm having a string request = "C is a programming language"
This list should match with the string and should return
C,C-sharp
How can i do this?

here is the solution with linq
var m = from t in target
where t[0] == 'C'
select t;

Using Linq and String.Contains:
var filtered = target.Where(str => str.Contains("C"));
Another option, without Linq, is to change the existing list using List<T>.RemoveAll:
target.RemoveAll(str => !str.Contains("C"));
If you really need a regex (for something more complex), you may also use:
Regex validate = new Regex(".a.", RegexOptions.IgnoreCase);
var filtered = target.Where(str => validate.Match(str).Success);

Related

Using linq to build a comma delimited string

I need to generate a string that has a comma delimited list, but no comma after the last element.
var x = new List<string>() { "a", "b", "c" };
should yield:
a,b,c
Yes, a very simple thing to do using "normal" techniques, but I hope with linq there is a more elegant way.
var cols =context.Database.SqlQuery<String>("select Column_Name from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = {0};", prefix + table);
No need Linq, just use String.Join
String.Join(",", new List<string>() { "a", "b", "c" });
String class provide Join method to join string array with delimiter.
Code:
var x = new List<string>() { "a", "b", "c" };
String.Join(",",x.ToArray());
documentation: http://msdn.microsoft.com/en-us/library/57a79xd0(v=vs.110).aspx
Although I strongly recommend you use the answer of Siva Charan, just for information here's an implementation in LinQ using Enumerable.Aggregate Method (IEnumerable, Func):
var result = x.Aggregate((c, n) => c + "," + n);

how to use a dynamic variable in orderby clause

am a newbie in linq.. am stuck with one scenario. ie,
i have to sort the search results based on user input.
user inputs are Last Name, First Name and Title. for input 3 drop downs are there and i have to sort result based on the values selected.
i tried
order = Request["orders"].Split(',');
var param = order[0];
var p1 = typeof(Test).GetProperty(param);
param = order[1];
var p2 = typeof(Test).GetProperty(param);
param = order[2];
var p3 = typeof(Test).GetProperty(param);
model.Test = (from tests in model.Test
select tests).
OrderBy(x => p1.GetValue(x, null)).
ThenBy(x => p2.GetValue(x, null)).
ThenBy(x => p3.GetValue(x, null));
but it doesn't works.
i want qry like this
from tests in model.Test
select tests).OrderBy(x => x.lastname).
ThenBy(x => x.firstname).ThenBy(x => x.Title);
order[0]== lastname but how can i use it in the place of OrderBy(x => x.order[0])..?
Thanks in advance.
i solved my case as follows
// list of columns to be used for sorting
List<string>order = Request["orders"].Split(',').ToList();
//map the column string to property
var mapp = new Dictionary<string, Func<Test, string>>
{
{"FirstName", x => x.FirstName},
{"LastName", x => x.LastName},
{"SimpleTitle", x => x.SimpleTitle}
};
//user inputted order
var paras = new List<Func<Test, string>>();
foreach (var para in order)
{
if(!string.IsNullOrEmpty(para))
paras.Add(mapp[para]);
}
//sorting
model.Test= model.Test.OrderBy(paras[0]).ThenBy(paras[1]).ThenBy(paras[2]);
Thanks all,
Actually you are looking for dynamic linq query than you can try out Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)
which allow to do like this
it means you can dynamically pass string propertyname to short you collection in orderby function
You can also read about : Dynamic query with Linq
You can compose the expression (any Expression) manually from pieces and then append it to the previous part of query. You can find more info, with example in "Sorting in IQueryable using string as column name".

LINQ create multiple new entities using a single ID field

I have a newbie LINQ question. I need to create two objects of same type from a list of strings. I need to append a text 'Direct' & "Indirect' to the string and use them as ID to create the two unique objects.
var vStrings = new List { "Milk", "Eggs", "Cheese" };
var vProducts = (from s in vStrings
select new Product { ID = s + "-Direct" })
.Union(
from s in vStrings
select new Product { ID = s + "-InDirect" });
You can see in the example above, I am using a Union to create two different objects, Is there a better way to rewrite this LINQ query?
Thanks for your suggestions
If you ever needed more suffixes, this might be a better way:
var strings = new List<string> { "Milk", "Eggs", "Cheese" };
var suffixes = new List<string> {"-Direct", "-InDirect"};
var products = strings
.SelectMany(_ => suffixes, (x, y) => new Product() {ID = x + y});
And it would only iterate over the original set of strings once.
This way isn't much shorter but I think it would be a little better such as there is only one Concat instead of many Union:
var vProducts2 = (from s in vStrings
select s + "-Direct").Concat(
from s in vStrings
select s + "-InDirect");

LINQ Group By into a Dictionary Object

I am trying to use LINQ to create a Dictionary<string, List<CustomObject>> from a List<CustomObject>. I can get this to work using "var", but I don't want to use anonymous types. Here is what I have
var x = (from CustomObject o in ListOfCustomObjects
group o by o.PropertyName into t
select t.ToList());
I have also tried using Cast<>() from the LINQ library once I have x, but I get compile problems to the effect of it being an invalid cast.
Dictionary<string, List<CustomObject>> myDictionary = ListOfCustomObjects
.GroupBy(o => o.PropertyName)
.ToDictionary(g => g.Key, g => g.ToList());
I cannot comment on #Michael Blackburn, but I guess you got the downvote because the GroupBy is not necessary in this case.
Use it like:
var lookupOfCustomObjects = listOfCustomObjects.ToLookup(o=>o.PropertyName);
var listWithAllCustomObjectsWithPropertyName = lookupOfCustomObjects[propertyName]
Additionally, I've seen this perform way better than when using GroupBy().ToDictionary().
For #atari2600, this is what the answer would look like using ToLookup in lambda syntax:
var x = listOfCustomObjects
.GroupBy(o => o.PropertyName)
.ToLookup(customObject => customObject);
Basically, it takes the IGrouping and materializes it for you into a dictionary of lists, with the values of PropertyName as the key.
This might help you if you to Get a Count of words. if you want a key and a list of items just modify the code to have the value be group.ToList()
var s1 = "the best italian resturant enjoy the best pasta";
var D1Count = s1.ToLower().Split(' ').GroupBy(e => e).Select(group => new { key = group.Key, value = group.Count() }).ToDictionary(e => e.key, z => z.value);
//show the results
Console.WriteLine(D1Count["the"]);
foreach (var item in D1Count)
{
Console.WriteLine(item.Key +" "+ item.Value);
}
The following worked for me.
var temp = ctx.Set<DbTable>()
.GroupBy(g => new { g.id })
.ToDictionary(d => d.Key.id);

LINQ: Entity string field contains any of an array of strings

I want to get a collection of Product entities where the product.Description property contains any of the words in a string array.
It would look something like this (result would be any product which had the word "mustard OR "pickles" OR "relish" in the Description text):
Dim products As List(Of ProductEntity) = New ProductRepository().AllProducts
Dim search As String() = {"mustard", "pickles", "relish"}
Dim result = From p In products _
Where p.Description.Contains(search) _
Select p
Return result.ToList
I already looked at this similar question but couldn't get it to work.
Since you want to see if search contains a word which is contained in the description of p you basically need to test for each value in search if it is contained in the description of p
result = from p in products
where search.Any(val => p.Description.Contains(val))
select p;
This is c# syntax for the lambda method since my vb is not that great
Dim result = From p in products _
Where search.Any(Function(s) p.Description.Contains(s))
Select p
You can use a simple LINQ query, if all you need is to check for substrings:
var q = words.Any(w => myText.Contains(w));
// returns true if myText == "This password1 is weak";
If you want to check for whole words, you can use a regular expression:
Matching against a regular expression that is the disjunction of all the words:
// you may need to call ToArray if you're not on .NET 4
var escapedWords = words.Select(w => #"\b" + Regex.Escape(w) + #"\b");
// the following line builds a regex similar to: (word1)|(word2)|(word3)
var pattern = new Regex("(" + string.Join(")|(", escapedWords) + ")");
var q = pattern.IsMatch(myText);
Splitting the string into words with a regular expression, and testing for membership on the words collection (this will get faster if you use make words into a HashSet instead of a List):
var pattern = new Regex(#"\W");
var q = pattern.Split(myText).Any(w => words.Contains(w));
In order to filter a collection of sentences according to this criterion all you have to do its put it into a function and call Where:
// Given:
// bool HasThoseWords(string sentence) { blah }
var q = sentences.Where(HasThoseWords);
Or put it in a lambda:
var q = sentences.Where(s => Regex.Split(myText, #"\W").Any(w => words.Contains(w)));
Ans From => How to check if any word in my List<string> contains in text by #R. Martinho Fernandes

Resources