I want to check if a String s, contains "a" or "b" or "c", in C#.
I am looking for a nicer solution than using
if (s.contains("a")||s.contains("b")||s.contains("c"))
Well, there's always this:
public static bool ContainsAny(this string haystack, params string[] needles)
{
foreach (string needle in needles)
{
if (haystack.Contains(needle))
return true;
}
return false;
}
Usage:
bool anyLuck = s.ContainsAny("a", "b", "c");
Nothing's going to match the performance of your chain of || comparisons, however.
Here's a LINQ solution which is virtually the same but more scalable:
new[] { "a", "b", "c" }.Any(c => s.Contains(c))
var values = new [] {"abc", "def", "ghj"};
var str = "abcedasdkljre";
values.Any(str.Contains);
If you are looking for single characters, you can use String.IndexOfAny().
If you want arbitrary strings, then I'm not aware of a .NET method to achieve that "directly", although a regular expression would work.
You can try with regular expression
string s;
Regex r = new Regex ("a|b|c");
bool containsAny = r.IsMatch (s);
If you need ContainsAny with a specific StringComparison (for example to ignore case) then you can use this String Extentions method.
public static class StringExtensions
{
public static bool ContainsAny(this string input, IEnumerable<string> containsKeywords, StringComparison comparisonType)
{
return containsKeywords.Any(keyword => input.IndexOf(keyword, comparisonType) >= 0);
}
}
Usage with StringComparison.CurrentCultureIgnoreCase:
var input = "My STRING contains Many Substrings";
var substrings = new[] {"string", "many substrings", "not containing this string" };
input.ContainsAny(substrings, StringComparison.CurrentCultureIgnoreCase);
// The statement above returns true.
”xyz”.ContainsAny(substrings, StringComparison.CurrentCultureIgnoreCase);
// This statement returns false.
This is a "nicer solution" and quite simple
if(new string[] { "A", "B", ... }.Any(s=>myString.Contains(s)))
List<string> includedWords = new List<string>() { "a", "b", "c" };
bool string_contains_words = includedWords.Exists(o => s.Contains(o));
public static bool ContainsAny(this string haystack, IEnumerable<string> needles)
{
return needles.Any(haystack.Contains);
}
As a string is a collection of characters, you can use LINQ extension methods on them:
if (s.Any(c => c == 'a' || c == 'b' || c == 'c')) ...
This will scan the string once and stop at the first occurance, instead of scanning the string once for each character until a match is found.
This can also be used for any expression you like, for example checking for a range of characters:
if (s.Any(c => c >= 'a' && c <= 'c')) ...
// Nice method's name, #Dan Tao
public static bool ContainsAny(this string value, params string[] params)
{
return params.Any(p => value.Compare(p) > 0);
// or
return params.Any(p => value.Contains(p));
}
Any for any, All for every
static void Main(string[] args)
{
string illegalCharacters = "!##$%^&*()\\/{}|<>,.~`?"; //We'll call these the bad guys
string goodUserName = "John Wesson"; //This is a good guy. We know it. We can see it!
//But what if we want the program to make sure?
string badUserName = "*_Wesson*_John!?"; //We can see this has one of the bad guys. Underscores not restricted.
Console.WriteLine("goodUserName " + goodUserName +
(!HasWantedCharacters(goodUserName, illegalCharacters) ?
" contains no illegal characters and is valid" : //This line is the expected result
" contains one or more illegal characters and is invalid"));
string captured = "";
Console.WriteLine("badUserName " + badUserName +
(!HasWantedCharacters(badUserName, illegalCharacters, out captured) ?
" contains no illegal characters and is valid" :
//We can expect this line to print and show us the bad ones
" is invalid and contains the following illegal characters: " + captured));
}
//Takes a string to check for the presence of one or more of the wanted characters within a string
//As soon as one of the wanted characters is encountered, return true
//This is useful if a character is required, but NOT if a specific frequency is needed
//ie. you wouldn't use this to validate an email address
//but could use it to make sure a username is only alphanumeric
static bool HasWantedCharacters(string source, string wantedCharacters)
{
foreach(char s in source) //One by one, loop through the characters in source
{
foreach(char c in wantedCharacters) //One by one, loop through the wanted characters
{
if (c == s) //Is the current illegalChar here in the string?
return true;
}
}
return false;
}
//Overloaded version of HasWantedCharacters
//Checks to see if any one of the wantedCharacters is contained within the source string
//string source ~ String to test
//string wantedCharacters ~ string of characters to check for
static bool HasWantedCharacters(string source, string wantedCharacters, out string capturedCharacters)
{
capturedCharacters = ""; //Haven't found any wanted characters yet
foreach(char s in source)
{
foreach(char c in wantedCharacters) //Is the current illegalChar here in the string?
{
if(c == s)
{
if(!capturedCharacters.Contains(c.ToString()))
capturedCharacters += c.ToString(); //Send these characters to whoever's asking
}
}
}
if (capturedCharacters.Length > 0)
return true;
else
return false;
}
You could have a class for your extension methods and add this one:
public static bool Contains<T>(this string s, List<T> list)
{
foreach (char c in s)
{
foreach (T value in list)
{
if (c == Convert.ToChar(value))
return true;
}
}
return false;
}
You can use Regular Expressions
if(System.Text.RegularExpressions.IsMatch("a|b|c"))
If this is for a password checker with requirements, try this:
public static bool PasswordChecker(string input)
{
// determins if a password is save enough
if (input.Length < 8)
return false;
if (!new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z", "Ä", "Ü", "Ö"}.Any(s => input.Contains(s)))
return false;
if (!new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}.Any(s => input.Contains(s)))
return false;
if (!new string[] { "!", "'", "§", "$", "%", "&", "/", "(", ")", "=", "?", "*", "#", "+", "-", "_", ".",
",", ";", ":", "`", "´", "^", "°", }.Any(s => input.Contains(s)))
return false;
return true;
}
This will set a password to have a min length of 8, have it use at least one uppercase char, at least one number, and at least one of the special chars
Related
I am writing a logic something like following code -
string myString = "ABCD";
if(myString.Contains("AB") && myString.Contains("C") && !myString.Contains("XYZ"))
{
//Do something
}
I want to write above code something like this:
string myString = "ABCD";
if( myString .contains any string from new[] { "AB", "C" } )
{
//Do Something
}
Can you please tell me, How can I achieve it?
Thanks in advance.
You want to check if the array has Any item such that myString Contains it:
using System.Linq;
...
// myString contains "AB" or "C"
if (new[]{ "AB", "C" }.Any(item => myString.Contains(item))) {
...
}
Put All it myString should contains both "AB" and "C"
// myString contains both "AB" and "C"
if (new[]{ "AB", "C" }.All(item => myString.Contains(item))) {
...
}
How about a little string extension method?
public static class StringExt
{
public static bool ContainsAnyOf(this string self, params string[] strings)
{
return strings.Any(self.Contains);
}
}
Then you can do this:
if (myString.ContainsAnyOf("AB", "C") && !myString.Contains("XYZ"))
{
//Do something
}
This sounds like a candidate for an extension method!
public static class StringExtensions
{
public static bool Contains(this string self, params string[] values)
{
for(int ix = 0; ix < values.Length; ++ix)
if(!self.Contains(values[ix]))
return false;
return true;
}
}
For your code like:
string myString = "ABCD";
if(myString.Contains("AB") && myString.Contains("C") && !myString.Contains("XYZ"))
{
//Do something
}
Let's do all your checks using LINQ:
var theStr = "ABCD";
var rules = new string[]{ "AB", "C", "!XYZ"};
if(rules.All(rule => rule[0] == '!' ? !theStr.Contains(rule.Substring(1)) : theStr.Contains(rule)))
{
//Do something
}
I do feel it's perhaps a mild abuse to put the "not" into the data by prefixing it with "!" though; consider making a Rule class that has a string and an Enum of RuleType that defines whether that string should be searched as "Contains" or "Not Contains".. Especially if you are ever going to want to find strings where one of the things you're looking for really is a string that starts with an "!"
You can use .All() because you are trying to check all strings present in an array
var checkElements = new string[]{ "AB", "C"};
//All element contains in myString then this will return true. It checks all elements
if(checkElements.All(x => myString.Contains(x)))
{
//Your business logic
}
If you want to check, if any string from an array checkElements, present in myString then you can use .Any() from System.Linq
var checkElements = new string[]{ "AB", "C"};
//Any one element contains in myString then this will return true.
if(checkElements.Any(x => myString.Contains(x)))
{
//Your business logic
}
This question already has answers here:
string.Replace (or other string modification) not working
(4 answers)
Closed 5 years ago.
I have two arrays, one that contains a set of characters to search for in a specific string and the other the set of strings with which to replace a specific character if found.
I'm trying to use the standard String.Replace() to modify the given string when the specific character is found. The method I'm trying to use detects that the string contains the character/characters of my array, enters the loop and runs the operation but at the end nothing is changed.
I'm not sure why or how to go to solve this. Below is my code and results.
static void Main(string[] args)
{
var wordToPass = "heyك";
wordToPass = wordToPass.MultiReplace();
Console.WriteLine(wordToPass);
Console.ReadKey();
}
The extension method to replace the characters:
public static class StringExtension
{
public static readonly char[] SignsArray = new char[] { 'ك', 'ـ', 'ض', 'ؤ', 'ا', 'ط', 'ئ', 'إ', 'ر', 'أ', ' ', 'ہ', 'ء', 'ب', 'ة', 'ت', 'ز',
'س', 'ص', 'ظ', 'ع', 'ج', 'ح', '´', 'ف', 'ث', '¶', '°', '؛', '·', '`' };
public static readonly string[] RepArray = new string[] { "SS", "UE", "OE", "AE", "C", "OE", "AE", "AA", "N", "A", "A", "A", "A", "E", "E", "E", "O", "O", "O",
"U", "U", "I", "I", "'", "Y", "E", "A", ".", ".", ".", "'"};
// Extension on String
public static string MultiReplace(this string stringValue)
{
HashSet<char> set = new HashSet<char>(SignsArray);
for (int i = 0; i < stringValue.Length; ++i)
{
var currentCharacter = stringValue[i];
string valueToReplace;
string replaceValue;
if (set.Contains(currentCharacter))
{
valueToReplace = Char.ToString(stringValue[i]);
replaceValue = RepArray[Array.IndexOf(SignsArray, currentCharacter)];
stringValue.Replace(Convert.ToString(currentCharacter), replaceValue);
}
}
return stringValue;
}
}
.Replace returns a new string, as System.String is immutable.
Consider reassigning.
stringValue = stringValue.Replace(Convert.ToString(currentCharacter), replaceValue);
My question is pretty simple.
Is there a short hand for
if (a == "p" || a == "l" || a == "g" || a == "z")
{
//do something
}
Is there an alternate to this. Meaning, Can I just do something like
if (a == ("p" || "l" || "g" || "z"))//this doesn't work
if (new[] { "p", "l", "g", "z" }.Contains(a))
If performance might be a concern, e.g. you have a large list of strings to check, or check it frequently, you should consider storing them in a HashSet<string>, e.g.
var mySet = new HashSet<string> { "p", "l", "g", "z" };
// later...
if (mySet.Contains(a))
Arrays.asList(new String[]{"a","b","c"}).contains("b");
C# code
var myList = new[] { "p", "l", "g", "z" };
if(myList.Contains(a))
{
//victory :)
}
You can use switch statement with fall thru:
switch (a) {
case "p":
case "l":
case "g":
case "z":
// do something
}
Better if you write an extension method like:
public static class MyExtension
{
public static bool In(this string c, params string[] items)
{
return items.Contains(c);
//OR //return items.Any(r => r == c);
}
}
and then use it like:
if ("a".In("p", "l", "a", "z"))
{
Console.WriteLine("Exists");
}
else
{
Console.WriteLine("Doesn't exist");
}
I have the following code, I am trying to get the strings which starts with capital, but I don't know how! without linq I can do it but inside LINQ... no idea!
string[] queryValues1 = new string[10] {"zero", "one", "two", "three", "four", "five", "six", "seven","nine", "ten" };
string[] queryValues2 = new string[3] { "A", "b", "c" };
var queryResult =
from qResult in queryValues1
from qRes in queryValues2
where qResult.Length > 3
where qResult.Length < 5
where qRes[0].StartWithCapital //how to check if qRes started with a capital letter?
select qResult + "\t" + qRes + Environment.NewLine;
foreach (var qResult in queryResult)
{
textBox1.Text += qResult;
}
The earlier solutions here all assume queryValues2 consists of strings with at least one character in them. While that is true of the example code, it isn't necessarily always true.
Suppose, instead, you have this:
string[] queryValues2 = new string[5] { "A", "b", "c", "", null };
(which might be the case if the string array is passed in by a caller, for example).
A solution that goes straight for qRes[0] will raise an IndexOutOfRangeException on the "" and a NullReferenceException on the null.
Therefore, a safer alternative for the general case would be to use this:
where !string.IsNullOrEmpty(qRes) && char.IsUpper(qRes[0])
Try this:
where char.IsUpper(qRes[0])
Check Char.IsUpper(qRes[0]).
where Char.IsUpper(qRes.FirstOrdefault())
It is the same as outside LINQ.
try something like this (in this code arr is a string[]):
from a in arr
where ((int)a.ToCharArray()[0] >= 65 && (int)a.ToCharArray()[0] <= 90)
select a
The gist is to check whether the first character's ASCII value lies in the range of capital letters or not.
static void Main(string[] args)
{
Console.Write("\nLINQ : Find the uppercase words in a string : ");
Console.Write("\n----------------------------------------------\n");
string strNew;
Console.Write("Input the string : ");
strNew = Console.ReadLine();
//string[] newStr = strNew.Split(' ');
var ucWord = WordFilt(strNew);
Console.Write("\nThe UPPER CASE words are :\n ");
foreach (string strRet in ucWord)
{
Console.WriteLine(strRet);
}
Console.ReadLine();
}
static IEnumerable<string> WordFilt(string mystr)
{
var upWord = mystr.Split(' ')
.Where(x=> !string.IsNullOrEmpty(x) && char.IsUpper(x[0]));
return upWord;
}
How to generate various combinations of opposite values using LinQ/C#
I have a list of operators in an array like "> < = + =" i also have a function which can return me the opposite value of each item in an array.Opposite value of ">" is "<" and so on.So considering the reverse operators for each and every value how to generate various possible combinations
Sample:
Problem Statement :
`string[] arrSample = new string[]{"!=","="};` //arrSample can be any object array with property values.The property can accept operator values like
!=,=,>,< etc..
Expected Output:
The various combinations considering the reverse operator would be
Output Sequence1: =,!=
Output Sequence2: !=,=
Output Sequence3: = , =
Output Sequence4: !=,!=
This turned out to be harder than it looks, but the following should demonstrate the idea.
There are two steps - create an array list pairs of each operator and its reverse and then recursively permute these together.
void DoProblem()
{
//string[] arrSample = new string[] { "!=", "=" };
string[] arrSample = new string[] { "!=", "<","+" };
string[][] arrPairs = (from op in arrSample select new string[]{op, GetReverse(op)}).ToArray();
List<Array> myList = new List<Array>();
myList.AddRange(arrPairs);
foreach (string x in Permute(0, myList))
{
Console.WriteLine(x);
}
}
List<string> Permute(int a, List<Array> x)
{
List<string> retval = new List<string>();
if (a == x.Count)
{
retval.Add("");
return retval;
}
foreach (Object y in x[a])
{
foreach (string x2 in Permute(a + 1, x))
{
retval.Add(y.ToString() + "," + x2.ToString());
}
}
return retval;
}
string GetReverse(string op)
{
switch (op) {
case "=":
return "!=";
case "!=":
return "=";
case "<":
return ">";
case "+":
return "-";
default:
return "";
}
}
NOTE: The permute function is based on the permute an Array of Arrays answer here: C# Permutation of an array of arraylists?
from operator in arrSample select operator + "," + ReverseOperator(operator)
Or did I miss something?
Do you want a union?
string[] arrSample = new string[]{"!=","="};
var list = (
from item in arrSample
select item + "," + item
).Union(
from revItem in arrSample
select revItem + "," + ReverseOperator(revItem)
);
List<string> final = new List<string>(list);
Please find the following easiest way to two string arrays with different combination
string[] roles = { "abc", "e", "f", "h" };
string[] allRoles = { "a", "b", "c", "abc", "e", "f", "g", "h", "i" };
foreach (string nextRole in allRoles)
{
if (Array.IndexOf(roles, nextRole) != -1)
{
Response.Write(nextRole + "<br/>");
}
}