C# LINQ Contains method with two clauses - c#

What is the best practice way to use two clauses in LINQ Contains method..
Title is string
This is my If statement :
if (oWeb.ParentWeb.Title.Contains("Ricky") || oWeb.ParentWeb.Title.Contains("John"))
I need solution like this :
if (oWeb.ParentWeb.Title.Contains("Ricky", "John"))

Since Title is string this actually has nothing to do with LINQ as the used Contains method is an instance method of string.
Assuming you have more strings to check, you can do something like that:
var strings = new[] {"Ricky", "John"};
if (strings.Any(oWeb.ParentWeb.Title.Contains))
// do something
But roryap's answer using a regex seems preferable (as long as the number of strings to check is not too big).

I don't think LINQ is the best option for that. Why not use regular expressions?
Regex.IsMatch(oWeb.ParentWeb.Title, "ricky|john", RegexOptions.IgnoreCase);

Contains takes only one parameter, so you cannot do it this way.
You can make an array of items, and check containment with it:
var titles = new[] {"Ricky", "John"};
if (titles.Any(t => oWeb.ParentWeb.Title.Contains(t))) {
...
}

Related

Remove characters in string in C#

I have the following field that is calling the database Phone_Number. I would like to remove the 1- when the number is displayed.
So instead of displaying 1-###-###-####, I would like to display ###-###-####.
I tried the following:
string x= Phone_Number;
x.Remove(0,1);
Response.Write(x);
However, it keeps displaying 1-###-###-####.
What am I doing wrong?
Strings are immutable in C# - String.Remove call does not modify original string. It creates the new string in which specified characters are deleted and returns it. You should display result of this method call instead:
Response.Write(x.Remove(0,2)); // you should remove 2 characters
Or
Response.Write(x.Substring(2));
You need to set the result to x. strings are immutable in C#:
x = x.Remove(0,1)
Another method would be:
if (x.StartsWith("1-")
x = x.Remove(0,2);
This has the benefit of doing nothing if you get a phone number without the leading 1-.
Thanks to commenter for pointing out my error.
As you see there are too many ways to remove substrings from strings. A new way that you can also use is a Regular Expression just in case the value you want to remove have a complex pattern in the future.
var x = phoneNumber;
var result = Regex.Match(x, #"^(1-)?(.*)$").Groups[2].Value;

c# "Cannot convert from 'string[]' to 'string'

I'm trying to make a list in string to get the usernames like this:
string[] whitelisted = { "example", "exampøle222", "example245"};
if (sentRequest.Sender.Username.ToLower().Contains(whitelisted))
You are checking if the username contains the list. You should be checking that the list contains the username.
whitelisted.Contains(sentRequest.Sender.Username.ToLower())
Your comparison is backwards. You need to see whether the array contains the string .
You probably want to check that the sentRequest.Sender.Username.ToLower() is present in the whitelisted list, right?
Then make it inverted if (whitelisted.Contains(sentRequest.Sender.Username.ToLower()))
The error you get says that the method you are calling i.e. string.Contains() can accept a string but cannot accept an array string[].
It can be done quite simply using the LINQ aggregate function.
string[] strings = {"example1","example2"};
string result = strings.Aggrigate((l,r)=>l+r);
You could also use the String.Join method
string[] strings = {"example1","example2"};
string result = String.Join("",strings);
However when I look at the rest of your code I would recommend solving the problem something like this.
if(whitelisted.IndexOf(sentRequest.Sender.Username.ToLower()) != -1)
That if statement will only be executed if the Username is in the white list.

Linq with dynamics "where parameter"

I have this case:
I create an array from a list like this:
String[] parameters = stringParametersToSearch.Split(' ');
The number of parameters can vary from 1 to n and I have to search for objects that in the description field containing all the occurrences of parameters
List<LookUpObject> result =
components.Where(o => o.LongDescription.Contains(parameters[0])).ToList<LookUpObject>();
if the parameter is 1 do so, but if they had two or more?
Currently to resolve this situation, I use an IF in which I build the LINQ expression for cases up to five parameters (maximum of real cases).
I can resolve this situation dynamically using LINQ ?
You either want to use Any or All, depending on whether you want to find objects where all of the parameters match or any of them. So something like:
var result = components
.Where(o => parameters.Any(p => o.LongDescription.Contains(p)))
.ToList();
... but change Any to All if you need to.
It's always worth trying to describe a query in words, and then look at the words you've used. If you use the word "any" or "all" that's a good hint that you might want to use it in the query.
Having said that, given the example you posted (in a now-deleted comment), it's not clear that you really want to use string operations for this. If the long description is:
KW=50 CO2=69 KG=100
... then you'd end up matching on "G=100" or "KG=1" neither of which is what you really want, I suspect. You should probably parse the long description and parameters into name/value pairs, and look for those in the query.

Combine string[] to string

Is there a quick way to pack an array of strings to a string?
More specifically,I have an array of strings like this:
string[] Operators = {"+","-","x","/"} and I would like to pack it to
string sOperators = "+-x/"
Of course, the obvious way is to read each item in the array and put it in the string individually, but is there a better way that people smarter than me can think of?
I have tried:
string sOperators="";
String.Join(sOperators,Operators);
Unfortunately, that won't work for me. Any thought?
Your code sample could just be incomplete but based on you've posted the problem is that you're not assigning the joined string anywhere. I think the following will do what you want;
string joined = String.Join(sOperators, Operators);
Join returns a new string, it does not make any changes to the arguments you pass it. You need to assign the return value to some field, property, constant, or variable in order to produce the desired result.
You can use String.Concat(Operators) (MSDN http://msdn.microsoft.com/en-us/library/k9c94ey1.aspx)
You can indeed use String.Join for this:
string sOperators = string.Join("", Operators);
I guess you just forgot to assign the result to a variable.

C# Regex: Get group names?

myRegex.GetGroupNames()
Seems to return the numbered groups as well... how do I get only the named ones?
A solution using the actual Match object would be fine as well.
Does using the RegexOptions.ExplicitCapture option when creating the regex do what you want ? e.g.
Regex theRegex = new Regex(#"\b(?<word>\w+)\b", RegexOptions.ExplicitCapture);
From MSDN:
Specifies that the only valid captures
are explicitly named or numbered
groups of the form (?<name>...). This
allows unnamed parentheses to act as
noncapturing groups without the
syntactic clumsiness of the expression
(?:...).
So you won't need to worry about whether users of your API may or may not use non-capturing groups if this option is set.
See the other comments/answers about using (?:) and/or sticking with "one style". Here is my best approach that tries to directly solve the question:
var named = regex.GetGroupNames().Where(x => !Regex.IsMatch(x, "^\\d+$"));
However, this will fail for regular expressions like (?<42>...).
Happy coding.
public string[] GetGroupNames(Regex re)
{
var groupNames = re.GetGroupNames();
var groupNumbers = re.GetGroupNumbers();
Contract.Assert(groupNames.Length == groupNumbers.Length);
return Enumerable.Range(0, groupNames.Length)
.Where(i => groupNames[i] != groupNumbers[i].ToString())
.Select(i => groupNames[i])
.ToArray();
}
Actually, this will still fail when the group name and number happen to be the same :\ But it will succeed even when the group name is a number, as long as the number is not the same as its index.

Categories

Resources