Checking if a string is NOT part of an Array (C#, Linq) - c#

I'm trying to use Linq to determine if a string is NOT in an array. The code I'm using is:
if (!stringArray.Any(soughtString.Contains)){
doStuff();}
but it's not working. Obviously creating a foreach loop would suffice, but I'd like to understand why this line isn't working. And yes, the file has using System.Linq;

You're not asking if the string is not in the array, you're asking if none of the strings in the array are sub-strings in some other string. Apparently at least one is, even though it's not equal.
You just want to do a simple Contains check:
if(!stringArray.Contains(soughtString))

You are currently passing the "Any" function the "Contains" method (which is then being passed each string in the array). In other, words:
array.Any(s => soughtString.Contains(s));
Likely, you want it the other way:
array.Any(s => s.Contains(soughtString));

Related

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.

Matching and replacing function expressions

I need to do some very light parsing of C# (actually transpiled Razor code) to replace a list of function calls with textual replacements.
If given a set containing {"Foo.myFunc" : "\"def\"" } it should replace this code:
var res = "abc" + Foo.myFunc(foo, Bar.otherFunc( Baz.funk()));
with this:
var res = "abc" + "def"
I don't care about the nested expressions.
This seems fairly trivial and I think I should be able to avoid building an entire C# parser using something like this for every member of the mapping set:
find expression start (e.g. Foo.myFunc)
Push()/Pop() parentheses on a Stack until Count == 0.
Mark this as expression stop
replace everything from expression start until expression stop
But maybe I don't need to ... Is there a (possibly built-in) .NET library that can do this for me? Counting is not possible in the family of languages that RE is in, but maybe the extended regex syntax in C# can handle this somehow using back references?
edit:
As the comments to this answer demonstrates simply counting brackets will not be sufficient generally, as something like trollMe("(") will throw off those algorithms. Only true parsing would then suffice, I guess (?).
The trick for a normal string will be:
(?>"(\\"|[^"])*")
A verbatim string:
(?>#"(""|[^"])*")
Maybe this can help, but I'm not sure that this will work in all cases:
<func>(?=\()((?>/\*.*?\*/)|(?>#"(""|[^"])*")|(?>"(\\"|[^"])*")|\r?\n|[^()"]|(?<open>\()|(?<-open>\)))+?(?(open)(?!))
Replace <func> with your function name.
Useless to say that trollMe("\"(", "((", #"abc""de((f") works as expected.
DEMO

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.

Select last element quickly after a .Split()

I have this code :
stringCutted = myString.Split("/"). // ???
and I'd like to store in stringCutted the last element of the string[] after the split, directly, quickly, without storing the splitted array in a variable and access to that element with array[array.length].
Is this possible in C#?
If you're using .NET 3.5 or higher, it's easy using LINQ to Objects:
stringCutted = myString.Split('/').Last();
Note that Last() (without a predicate) is optimized for the case where the source implements IList<T> (as a single-dimensional array does) so this won't iterate over the whole array to find the last element. On the other hand, that optimization is undocumented...
stringCutted=myString.Split("/").Last()
But, just FYI, if you're trying to get a filename from a path, this works heaps better:
var fileName=System.IO.Path.GetFileName("C:\\some\path\and\filename.txt");
// yields: filename.txt
Since you want a solution that returns the last element directly, quickly, without store the splitted array, i think this may be useful:
stringCutted = myString.Substring(myString.LastIndexOf("/")+1);
Use LINQ
"t/e/s/t".Split("/").Last();
For using this code, I skip last element from the Url link.
string url = Request.Url.ToString().Substring(0, Request.Url.ToString().LastIndexOf('/'));
For Addition:
When string format like 'a/b/c/d' then
yourstring.Split("/").Last();
When string format like \head_display\27_[Item A]\head_image\original_image\1_Item A.png
yourstring.Split("\\").Last();
first '\' actually to skip second '\'

Categories

Resources