simple string compare not so simple  
Author Message
gmedia





PostPosted: Visual C# General, simple string compare not so simple Top

I am doing jsut a simple little string compare and the values are equal, however, I cannot get them to see that they are equal. Unless I am so Dyslexic I cannot read two simple strings.

Here is the code:

public bool test_ArPermHa****ission(string prefix, string action)

{

string permission = prefix + action;

bool test = false;

foreach (string p in arPerm)

{

//the values that fail: p = auth_update and permission = auth_update

if (String.Equals(p.ToString(), permission.ToString()))

{

return true;

}

}

return false;

}

I got so fed up with the string.equals I also tried the following:

(p.ToString() == permission.ToString());

(p == permission.ToString());

(p.ToString() == permission);

(p == permission);

(String.Equals(p.ToString(), permission.ToString()));

(String.Equals(p.ToString(), permission));

(String.Equals(p, permission.ToString()));

(String.Equals(p, permission));

(p.ToString().CompareTo(permission.ToString()) == 0);

(p.ToString().CompareTo(permission.ToString()) == 0);

(p.CompareTo(permission.ToString()) == 0);

(p.ToString().CompareTo(permission) == 0);

(p.CompareTo(permission) == 0);

 

When this didn't work I removed the underscore to make the value one word.



Visual C#8  
 
 
Formerly Known As Eam





PostPosted: Visual C# General, simple string compare not so simple Top

You know, if all those methods are failing, it's usually a sign that the strings may not be totally equal.

If you need a case-insensitive compare, try "string.Compare(s1, s2, true) == 0"
Or if you want to be fancy about it "s1.Equals(s2, StringComparison.InvariantCultureIgnoreCase)"
It's probably safe to leave out the "ToString()" call on your string (believe it or not).

And for some unsolicited advice: You may want to reconsider doing a linear search through your string collection if it's big at all. You will probably see better performance using a binary search on a sorted array.


 
 
OmegaMan





PostPosted: Visual C# General, simple string compare not so simple Top

In the case of...what exactly are the strings in question Could case be getting in the way Here is a test I did:


public static void TestEquality()
{
string one = "This is radio clash";
string two = "This is radio clash";
string three = "This is Radio clash";

if (one == two) // True
    Console.WriteLine("1 == 2");

if (one.Equals(two)) // True
    Console.WriteLine("1 Equals 2");

if (one == three) // False
   Console.WriteLine("1 == 3");

if (one.Equals(three)) // false
    Console.WriteLine("1 Equals 3");

if (one.Equals(three, StringComparison.InvariantCultureIgnoreCase))
    Console.WriteLine("1 Equals (Ignore) 3"); // True

}

 


The comments show if they came out true or false...


 
 
Michael Letterle





PostPosted: Visual C# General, simple string compare not so simple Top

Also sometimes doing a .Trim() on both of them before hand is a good idea....I would recommend putting a break point at the comparision and seeing what's really what....


 
 
Felan





PostPosted: Visual C# General, simple string compare not so simple Top

I see in your example the two string are intended to be:

//the values that fail: p = auth_update and permission = auth_update

I also see that you create permission in this line:

string permission = prefix + action;

I didn't find a way to make this fail when the strings were textually equivalent, but I wonder if in your assignment to permission you neglected to include a "_" in the combination   Should the line actually be:

string permission = prefix + "_" + action;

If that isn't the problem, have you inspected the values of the strings in the de****  

If none this helps then can you post a complete minimal example of how you get this problem, for example I tried to reconstruct what you were doing as minimally and closely as I could:

static void Main(string[] args)
  {
   string[] arPerm = new string[] { "auth_update", "auth_delete" };
   string prefix = "auth_";
   string action = "update";

   string permission = prefix + action;

   Console.WriteLine("Using String.Equals(p.ToString(), permission.ToString()))");
   foreach (string p in arPerm)
   {
    Console.Write("For entry \"" + p + "\" the comparison is ");
    if (String.Equals(p.ToString(), permission.ToString()))
    {
     Console.WriteLine("TRUE");
    }
    else
    {
     Console.WriteLine("FALSE");
    }
   }

   Console.WriteLine(Environment.NewLine + "Using: if (String.Equals(p, permission))");
   foreach (string p in arPerm)
   {
    Console.Write("For entry \"" + p + "\" the comparison is ");
    if (String.Equals(p, permission))
    {
     Console.WriteLine("TRUE");
    }
    else
    {
     Console.WriteLine("FALSE");
    }
   }

   Console.WriteLine(Environment.NewLine + "Using: if (p == permission)");
   foreach (string p in arPerm)
   {
    Console.Write("For entry \"" + p + "\" the comparison is ");
    if (p == permission)
    {
     Console.WriteLine("TRUE");
    }
    else
    {
     Console.WriteLine("FALSE");
    }
   }
  }

The output of this program was:

Using String.Equals(p.ToString(), permission.ToString()))
For entry "auth_update" the comparison is TRUE
For entry "auth_delete" the comparison is FALSE

Using: if (String.Equals(p, permission))
For entry "auth_update" the comparison is TRUE
For entry "auth_delete" the comparison is FALSE

Using: if (p == permission)
For entry "auth_update" the comparison is TRUE
For entry "auth_delete" the comparison is FALSE

HTH,

Todd


 
 
gmedia





PostPosted: Visual C# General, simple string compare not so simple Top

All,

Thanks so much for the quick feedback. Trim function did the trick. The test is now:

p.Trim().Equals(permission.Trim(), StringComparison.InvariantCultureIgnoreCase) and it works.

Thanks again.


 
 
gmedia





PostPosted: Visual C# General, simple string compare not so simple Top

right, that was a typo I made when posting the script.
 
 
James Curran





PostPosted: Visual C# General, simple string compare not so simple Top

T**** both operands and doing case-insensitive compare every time through the loop is a bit of a waste, when one side, presumably (arPerm) is a fixed array that you have total control over. And doing a manual search when there are built in method to do it is also a waste. The method can be reduced to :

string[] arPerm = new string[] { "auth_update", "auth_delete" };
public bool test_ArPermHa****ission(string prefix, string action)
{
   string permission = (prefix + action).Trim().ToLower();
   return Array.Exists(arPerm, delegate(string p) { return p == permission; });
}

Now, if you don't have complete control over arPerm...It's not defined as a fixed array as above, but instead, say, read from a database, then the Trim() and ToLower() would need to be done on the string, but they should be done as teh string are loaded into the array.



 
 
OmegaMan





PostPosted: Visual C# General, simple string compare not so simple Top

Nice example of using the predicate!


 
 
gmedia





PostPosted: Visual C# General, simple string compare not so simple Top

Why do things the easy way

THanks for the help. I have implemented this instead of my 12 line loop. I did have to make one modification, putting a trim on p.

string permission = (prefix + action).Trim().ToLower();

return Array.Exists(arPerm, delegate(string p) { return p.Trim() == permission; });


 
 
James Curran





PostPosted: Visual C# General, simple string compare not so simple Top

I did have to make one modification, putting a trim on p.

No. p is an item from the array. It should not need to be trimmed every time you do the test. It should not have extra spaces to start with, but even if it does, it should be trimmed when it is first placed in the array.