I have following if condition:
if (!string.IsNullOrEmpty(str) &&
(!str.ToLower().Contains("getmedia") && !str.ToLower().Contains("cmsscripts") &&
!str.ToLower().Contains("cmspages") && !str.ToLower().Contains("asmx") &&
!str.ToLower().Contains("cmsadmincontrols"))
)
I am trying to create an array of keywords instead of putting multiple AND conditions, could you please help?
string[] excludeUrlKeyword = ConfigurationManager.AppSettings["ExcludeUrlKeyword"].Split(',');
for (int i = 0; i < excludeUrlKeyword.Length; i++)
{
var sExcludeUrlKeyword = excludeUrlKeyword[i];
}
How to build the same if condition from the array?
You can use LINQ's All or Any method to evaluate a condition on array elements:
// Check for null/empty string, then ...
var lower = str.ToLower();
if (excludeUrlKeyword.All(kw => !lower.Contains(kw))) {
...
}
Note that this is not the fastest approach: you would be better off with a regex. As an added bonus, regex would prevent "aliasing", when you discard a string with a keyword appearing as part of a longer word.
If you would like to try regex approach, change ExcludeUrlKeyword in the config file from comma-separated getmedia,cmsscripts,cmspages,asmx to pipe-separated getmedia|cmsscripts|cmspages|asmx, so that you could feed it directly to regex:
var excludeUrlRegex = ConfigurationManager.AppSettings["ExcludeUrlKeyword"];
if (!Regex.IsMatch(str.ToLower(), excludeUrlRegex)) {
...
}
Linq Any should do this
if (!string.IsNullOrEmpty(str) && !excludeUrlKeyword.Any(x => str.ToLower().Contains(x)))
Related
I have a number of elements in an array, I would like to check if a string is equal to any of these elements in the array. The number of elements in the array can change in number.
I have counted the number of elements in the array hoping to get somewhat of an advantage but haven't been able to come up with a solution.
int ArrayCount = FinalEncryptText.Count();
foreach (string i in FinalEncryptText)
{
}
Using the foreach implementation you have provided, you could include an if condition with String.Equals(string) - as Sean pointed out earlier.
But it's worth noting that String.Equals(string) without additional arguments is equivalent to using the == operator. So it's better if you specify the StringComparison type so that you express what kind of comparison you wish to perform.
For example, you could do something like this:
foreach (string element in myStringArray)
{
if(element.Equals("foo", StringComparison.CurrentCultureIgnoreCase))
...
}
You could even include the evaluation as a predicate in a LINQ query. For example, let's say you wanted to see which strings passed the evaluation:
var matches = myStringArray
.Where(element => element.Equals("foo", StringComparison.CurrentCultureIgnoreCase));
You can read more about comparing strings here.
I'm not sure what your method looks like, but I'm assuming.. you're given a random array of strings.. and you want to find a certain element in that array. Using a foreach loop:
public string Check(string[] FinalEncryptText)
{
foreach (string i in FinalEncryptText)
{
//let's say the word you want to match in that array is "whatever"
if (i == "whatever")
{
return "Found the match: " + i;
}
}
}
Using a regular for loop:
public string Check(string[] FinalEncryptText)
{
for (int i = 0; i < FinalEncryptText.Count; i++)
{
//let's say the word you want to match in that array is "whatever"
if (FinalEncryptText[i] == "whatever")
{
//Do Something
return "Found the match: " + FinalEncryptText[i];
}
}
}
Now if you already have a fixed array.. and you're passing in a string to check if that string exists in the array then it would go something like this:
public string Check(string stringToMatch)
{
for (int i = 0; i < FinalEncryptText.Count; i++)
{
//this will match whatever string you pass into the parameter
if (FinalEncryptText[i] == stringToMatch)
{
//Do Something
return "Found the match: " + FinalEncryptText[i];
}
}
}
You could use the String.Equals method in an if statement. More info on String.Method here: String.Equals Method.
if(firstString.Equals(secondString))
{
//whatever you need to do here
}
I'm loading CSV Files into a IEnumerable.
string[] fileNames = Directory.GetFiles(#"read\", "*.csv");
for (int i = 0; i < fileNames.Length; i++)
{
string file = #"read\" + Path.GetFileName(fileNames[i]);
var lines = from rawLine in File.ReadLines(file, Encoding.Default)
where !string.IsNullOrEmpty(rawLine)
select rawLine;
}
After that I work with the Data but now there are couple of Files that are pretty much empty and only have ";;;;;;" (the amount varies) written in there.
How can I delete those rows before working with them and without changing anything in the csv files?
If the amount of ; characters per line is variable, this is what your "where" condition should look like:
where !string.IsNullOrEmpty(rawLine) && !string.IsNullOrEmpty(rawLine.Trim(';'))
rawLine.Trim(';') will return a copy of the string with all ; characters removed. If this new string is empty, it means this line can be ignored, since it only contained ; characters.
You can't remove anything from an IEnumerable(like from a List<T>), buty ou can add a filter:
lines = lines.Where(l => !l.Trim().All(c => c == ';'));
This won't delete anything, but you won't process these lines anymore.
You can't remove rows from an enumerable - https://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx.
Instead try creating a new array with the filtered data or filter it on the where clause that you presented like:
string[] fileNames = Directory.GetFiles(#"read\", "*.csv");
for (int i = 0; i < fileNames.Length; i++)
{ string file = #"read\" + Path.GetFileName(fileNames[i]);
var lines = from rawLine in File.ReadLines(file, Encoding.Default) where !string.IsNullOrEmpty(rawLine) && rawLine != ";;;;;;" select rawLine;}
There are multiple solution.
Convert enumerable to List, then delete from List. This is bit expensive.
Create one function. // You can apply multiple filter in case required.
public IEnumrable<string> GetData(ref IEnumrable<string> data)
{
return data.Where(c=> !String.Equals(c,"<<data that you want to filter>>");
}
As another option to read CSV file is to make use of TextFieldParser class. It has CommentTokens and Delimiters which may help you on this.
Specifying ; as a CommentTokens may help you.
Tutorial
I have a method which recieves an array of strings from another method.
This array contains several strings, for days, moviegenres etc.
I need to check if the array contains any of the moviegenres, and if so I need that specific value.
here is what I have now:
if (eventsSelected.Contains("act") ||
eventsSelected.Contains("adv") ||
eventsSelected.Contains("ani") ||
eventsSelected.Contains("doc") ||
eventsSelected.Contains("dra") ||
eventsSelected.Contains("hor") ||
eventsSelected.Contains("mys") ||
eventsSelected.Contains("rom") ||
eventsSelected.Contains("sci") ||
eventsSelected.Contains("thr"))
{
//get the value that is in the array contains.
}
Because my code checks for 10 different values how can I find out which value is true?
So let's say the array contains the value "act" how can I get that specific value?
foreach(var match in new [] {"act", "adv"}.Where(eventsSelected.Contains))
{
//do stuff
}
Or if you just need the first one
var match = Array.Find(new[] { "act", "adv" }, eventsSelected.Contains);
if (!string.IsNullOrEmpty(match))
{
// If you just want the first match
}
The match field contains the token you were searching on, so act or adv.
Either use multiple if or use a string[] and Array.FindIndex:
string[] tokens = {"adv", "ani", "doc" .... };
int index = Array.FindIndex(tokens, t => eventsSelected.Contains(t));
if(index >= 0)
{
Console.WriteLine("First value found was: " + tokens[index])
}
You can use Intersect
var values = new[] {"act", "adv", "ani", etc};
var matches = values.Intersect(eventsSelected);
//matches contains all matching values
Similar to the answer from Tim, but using LINQ rather than Array functions:
string[] tokens = {"adv", "ani", "doc" .... };
string firstMatch = eventsSelected.FirstOrDefault(s => tokens.Contains(s));
if (firstMatch != null)
{
// Do something with firstMatch
}
I couldn't help but notice that you've written your tokens in sorted order so just for the fun of it you could do:
string[] sortedTokens = {"act", "adv", "ani", ... };
int index = Array.FindIndex(eventsSelected, e => Array.BinSearch(sortedTokens, e) > 0)
And then proceed as in Tim's answer, except that this time, index is the index from eventsSelected. This gives you O(nlog(k)) time complexity, where n is the size of eventsSelected and k is the size of tokens (other answers give O(nk), not that it matters much).
let assume we have an array like this:
var caps = new[] { "1512x", "001xx", "27058", "201xx", "4756x" };
(original array is huge and come from another linq query)
What I need is to create a LINQ statement accepting a value and tries to match with one of the values on the foreseen array.
For example if I use "15121" I need to match the "1512x" value on the array and return it.
Obviously, if I use "27058" it finds the exact match and simply return it.
Is it possible in LINQ?
The "wildcard" char on the array is "x", but I can change it.
Thanks in advance!
Valerio
You can use regular expressions:
var value = "15121";
var caps = new[] { "1512x", "001xx", "27058", "201xx", "4756x" };
var match = caps
.FirstOrDefault(c => new Regex("^" + c.Replace("x", "[0-9]") + "$").IsMatch(value));
if (match != null)
Console.WriteLine("{0} matches {1}", value, match);
The "pattern" 001xx is converted into the regular expression ^001[0-9][0-9]$ and so on. Then the first matching regular expressions is found.
But if the caps is huge it might not perform so well because each regular expression has to be compiled and converted into a state machine until a match is found.
Assuming you have a predicate method, something like this (or something equivalent using Regex, as described in another answer):
static bool Match(string pattern, string exact)
{
if(pattern.Length != exact.Length) return false;
for(var i = 0; i < pattern.Length; i++)
if(pattern[i] != exact[i] && pattern[i] != 'x')
return false;
return true;
}
Then the LINQ query can look like this:
var found = caps.Single(x => Match(x, yourSearch));
Good Morning,
In an if statement if we want to check if a string contains a value, we have :
if (string.Contains("Value1"))
{
}
How can we make the string compare with more values in an if statement without keep writing the whole statement? For example to avoid the below statement
if ((string.Contains("Value1") && (string.Contains("Value2")) && (string.Contains("Value3")))
{
}
Thank you
So, basically, you want to check if all of your values are contained in the string . Fortunately (with the help of LINQ), this can by translated almost literally into C#:
var values = new String[] {"Value1", "Value2", "Value3"};
if (values.All(v => myString.Contains(v))) {
...
}
Similarly, if you want to check if any value is contained in the string, you'd substitute All by Any.
Well, you could use LINQ:
string[] requiredContents = { "Foo", "Bar", "Baz" };
if (requiredContents.All(x => text.Contains(x))
{
...
}
Note that just like the short-circuiting && operator, All will stop as soon as it finds a value which doesn't satisfy the condition. (If you want to use Any in a similar way elsewhere, that will stop as soon as it finds a value which does satisfy the condition.)
I wouldn't bother for only a reasonably small number though. Without the extraneous brackets, it's really not that bad:
if (text.Contains("foo") && text.Contains("bar") && text.Contains("Baz"))
{
}
I would only start using the more general form if either there were genuinely quite a few values (I'd probably draw the line at about 5) or if the set of values was being passed in as a parameter, or varied in some other way.
As you need "your" string to contains all values:
var values = new String[] {"Value1", "Value2", "Value3"};
var s = yourString;
if (values.Count(v => s.Contains(v)) == values.Length) {
...
}
Is this the best solution? Probably not. Is it readable and extendable? Yes.
var matches = {"string1", "string2", "string3","string-n"};
var i = 0;
foreach(string s in matches)
{
if(mystring.Contains(s))
{
i++;
}
}
if(i == matches.Length)
{
//string contains all matches.
}
if(stringArray.Any(s => stringToCheck.Contains(s)))
If you want to ensure that it contains all the substrings, change Any to All:
if(stringArray.All(s => stringToCheck.Contains(s)))