C# Check List against part of string - c#

I have a list which contains values such as:
readies action
uses action
begins to cast action
I want to compare a string to match against this list and return a boolean based on that. So for example:
string compare = "The Manipulator uses action";
To do this I have tried two different methods, the first being:
if (mylist.Contains(compare)) { //True }
and the second (with Linq):
if (mylist.Any(str => str.Contains(compare))) { //True }
The problem I'm having is both of these methods match against an extended string. What I mean by that is if compare == "uses action" the statement returns true, but if compare == "The Manipulator uses action" the statement returns false.
Any help on fixing this would be most appreciated! :)

I'm not totally following what you're looking for, so there are 2 different solutions, besed on expected outcome.
If you're only trying to match exactly the same string from within the list Any is the way to go, but you should use == instead of Contains:
if (mylist.Any(str => str == compare)) { //True }
If you'd like extended string to also match, you use Contains, but instead of calling str.Contains(compare) call compare.Contains(str):
if (mylist.Any(str => compare.Contains(str))) { //True }

Related

Is there a function to check whether a path is included in the path?

I would like to check the path.
For example, I want a method that has functionality below.
Two path string is "C:\Document\test", "C:Document\test2".
And If "C:\Document\test" is compared with "C:Document\test2" then the result is expected false because "C:\Document\test" is not included in "C:Document\test2".
Another example is
Two path string is "C:\Document\test", "C:Document\test\test2".
If "C:\Document\test" is compared with "C:Document\test\test2" then the resulut is expected true because "C:\Document\test" is included in "C:Document\test\test2".
Is there a method that has functionality the above in C#?
Thanks for reading.
You could use string comparison for the purpose. For example,
public static bool ComparePath(string path1,string path2)
{
return NormalizePath(path2).Contains(NormalizePath(path1));
}
public static string NormalizePath(string path)
{
if(path.Trim().Last().Equals(Path.DirectorySeparatorChar))
return path.Trim().ToLower();
return $"{path.Trim()}{Path.DirectorySeparatorChar}".ToLower();
}
You need to include the DirectorySeparatorChar to mark end of path.
Example,
ComparePath(#"C:\Document\test",#"C:\Document\test\2"); // True
ComparePath(#"C:\Document\test",#"C:\Document\test2"); // False
I think the PathUtil.IsDescendant(String, String) Method is exactly what you Need. You find the documentation here.
var res = PathUtil.IsDescendant("C:\\Test\\Test1\\", "C:\\Test\\Test1\\Test2.txt");
res = PathUtil.IsDescendant("C:\\Test\\Test", "C:\\Test\\Test2");
The first will return trueand the second will return false

Using List.Contains method to find a string returns false but manual comparison return true

I have a list of strings and I am trying to determine whether one of them match a needle string. That list of strings contains the needle at the first index, and my code has the following behavior:
listOfStrings.Contains(needle); // return false
listOfStrings[0] == needle; // return true
Why does the Contains method have a different behavior than the default comparison beahavior, and what should I modify so that it has the same be havior?
To give more insight about the problem I am facing, I am handling strings which come from WinForm textboxes. They represent input paths and a destination folder.
if (!destinationPath.EndsWith("\\"))
{
destinationPath += "\\";
}
List<string> inputDirectories = new List<string>(inputPaths.Length);
foreach (string path in inputPaths)
{
inputDirectories.Add(Path.GetDirectoryName(path).ToLower());
}
bool comparison1 = inputDirectories[0] == Path.GetDirectoryName(destinationPath.ToLower()); // return true
bool comparison2 = inputDirectories.Contains(Path.GetDirectoryName(destinationPath.ToLower())); // return false
You haven't said what Type your list is, but if it's an ArrayList or a List<object> the comparison will give a different result from List<string>, because the Compare method will compare objects rather than strings.
To understand this, try running the following code:
string s1 = "A";
string s2 = "AB";
s1 += "B";
Console.WriteLine(s1 == s2); // True
Console.WriteLine((object)s1 == (object)s2); // False
s1 and s2 are equal when compared as strings, but are different objects.
If you are already using List<string> and are looking for a case-insensitive Contains, try the technique in the accepted answer to this question.

Contains and Regex Returns true but not with exact match

I am stumped on how to figure out the condition. Basically I have information from a list into a string to use Contains and Regex. I need to figure out if the user selected the "Other" option and if so then do something. However in the same list there are additional values to choose from that start with "Other" as well.
Example Data:
Fire Material
Other
Other Chemical
Example Code:
if(MaterialList.ToString().Contains("Other"))
{
"Do This If Other Is Selected";
}
else
{
"Do That If Other Isn't Selected";
}
It works fine if the user selects just "Other" however, if the user doesn't select "Other" but selects "Other Chemical" the condition still returns true.
I have also tried the following and it behaves the same:
public static bool ExactMatch(string input, string match)
{
return Regex.IsMatch(input, string.Format(#"{0}", Regex.Escape(match)));
//actually doesn't find the exact match - just a portion of the string
}
Probably Contains or Match shouldn't be used but not sure how to solve the problem.
Looks like you could use Linq instead:
if (MaterialList.Any(m => m == "Other"))
...
You can use String.EndsWith() function in your case
From MSDN:
Determines whether the end of this string instance matches the
specified string.
try this:
if(MaterialList.ToString().EndsWith("Other"))
{
"Do This If Other Is Selected";
}
else
{
"Do That If Other Isn't Selected";
}
Why not use
public static bool ExactMatch(string input, string match)
{
return input == match;
}
or you're sick by do-everything-with-regex?
Thanks all. Figured it out.
if(MaterialsList.ToString().Split('\t').Contains("Other"))

Why String.Equals is returning false?

I have the following C# code (from a library I'm using) that tries to find a certificate comparing the thumbprint. Notice that in the following code both mycert.Thumbprint and certificateThumbprint are strings.
var certificateThumbprint = AppSettings.CertificateThumbprint;
var cert =
myStore.Certificates.OfType<X509Certificate2>().FirstOrDefault(
mycert =>
mycert.Thumbprint != null && mycert.Thumbprint.Equals(certificateThumbprint)
);
This fails to find the certificate with the thumbprint because mycert.Thumbprint.Equals(certificateThumbprint) is false even when the strings are equal. mycert.Thumbprint == certificateThumbprint also returns false, while mycert.Thumbprint.CompareTo(certificateThumbprint) returns 0.
I might be missing something obvious, but I can't figure out why the Equals method is failing. Ideas?
CompareTo ignores certain characters:
static void Main(string[] args)
{
var a = "asdas"+(char)847;//add a hidden character
var b = "asdas";
Console.WriteLine(a.Equals(b)); //false
Console.WriteLine(a.CompareTo(b)); //0
Console.WriteLine(a.Length); //6
Console.WriteLine(b.Length); //5
//watch window shows both a and b as "asdas"
}
(Here, the character added to a is U+034F, Combining Grapheme Joiner.)
So CompareTo's result is not a good indicator of a bug in Equals. The most likely reason of your problem is hidden characters. You can check the lengths to be sure.
See this for more info.
You may wish to try using an overload of String.Equals that accepts a parameter of type StringComparison.
For example:
myCert.Thumbprint.Equals(certificateThumbprint, StringComparison.[SomeEnumeration])
Where [SomeEnumeration] is replaced with one of the following enumerated constants:
- CurrentCulture
- CurrentCultureIgnoreCase
- InvariantCulture
- InvariantCultureIgnoreCase
- Ordinal
- OrdinalIgnoreCase
Reference the MSDN Documentation found here.
Sometimes when we insert data in database it stores some spaces like "question ". And when you will try to compare it with "question" it returns false. So my suggestion is: please check the value in database or use Trim() method.
In your case, please try:
mycert.Thumbprint != null && mycert.Thumbprint.trim().equals(certificateThumbprint.trim())
I think it will return true if any record will exist.

c# string Compare

I am trying to create list filter in .net MVC4 C#.
I have ajax query that sends string to controller and according to matches in database it returns number of records.
So when the String is IsNullOrEmpty() and IsNullOrWhiteSpace() it brings me fine result.
I have problem in matching values now.
Although it seemed me easy so i tried-
Controller
public ActionResult SearchAccountHead(string accountHead)
{
var students = from s in db.LedgerTables
select s;
List<LedgerModel> ledge = null;
if (!String.IsNullOrEmpty(accountHead))
{
//Returns non-empty records
}
if (String.IsNullOrEmpty(accountHead) && String.IsNullOrWhiteSpace(accountHead))
{
//Checks whether string is null or containing whitespace
//And returns filtered result
}
return PartialView(ledge);
}
Now if I have string that doesn't match with string I have been using in controller then I tried mapping it-
if (String.IsNullOrEmpty(accountHead) && String.IsNullOrWhiteSpace(accountHead) && !String.Compare(accountHead))
if (String.IsNullOrEmpty(accountHead) && String.IsNullOrWhiteSpace(accountHead) && !String.Compare(AccountHead,ledge.AccountHead))
But in both cases it didn't work.
How can I get into second method when string doesn't match?
You can't apply string.Compare with !, since string.Compare would return an integer value. If you are comparing string for equality then its better if you use string.Equals, it also has an overload which does case insensitive comparison.
You can have the check like:
if (String.IsNullOrWhiteSpace(accountHead) &&
!String.Equals(AccountHead, ledge.AccountHead,StringComparison.InvariantCultureIgnoreCase))
As a side note you can remove
if (String.IsNullOrEmpty(AccountHead) && String.IsNullOrWhiteSpace(AccountHead))
and just use
if (String.IsNullOrWhiteSpace(AccountHead))
since string.IsNullOrWhiteSpace checks for empty strings as well.
You can use string.Equals() and pass it an option for comparison logic. Something like this:
AccountHead.Equals(ledge.AccountHead, StringComparison.InvariantCultureIgnoreCase)
This will compare AccountHead and ledge.AccountHead in a case-insensitive manner using invariant culture rules. There are additional options to choose from as well.
You can use String.Compare to do the same as String.Equals, however, it's a bit less succinct e.g.
String.Compare(AccountHead, ledge.AccountHead, StringComparison.OrdinalIgnoreCase) <> 0
Here's the shorter way...
!AccountHead.Equals(ledge.AccountHead, StringComparison.OrdinalIgnoreCase);
You can keep it simple and write something like this !(accountHead == ledge.AccountHead).
You don't need comparison as i see, but to check if strings are equal or not. Usually Equals is the best way to do that, but "==" does semantic and object.ReferenceEquals -- referential comparison. So i would go with that one.
Hope this helps

Categories