[Tech] Bit of a lengthy if statement...

Nanor

Well-Known Member
I'm doing an assignment for college and was wondering if I could query y'all. I have 6 text boxes and I have to check to make sure each text box has a unique value. At the minute the only way I can think to check this is to use an if statement along the lines of

Code:
if (txtOne.Text = txtTwo.Text OR txtOne.Text = txtThree.Text OR ...

I'm sure you understand it's a pretty massive if statement. Is there any quick way I can check to see if each textbox contains a unique value?

You'll also be thrilled to hear I'm using VB.net.

Cheers!

EDIT: Also each value is an integer, should that matter.
 

BiG D

Administrator
Staff member
Not sure how VB handles arrays, but a few potential options:

  • Make an array to store the values. Loop through the textboxes and check if their value is already in the array. If not add it and continue.
  • Loop through the textboxes and add their values to the array. Do an array.unique() (or whatever) and check if it still has the same number of elements
  • Do the comparison using two nested loops. Make sure you exempt them from being compared to themselves.
 

Iron_fist

Super Moderator
Staff member
you could try using XOR

Code:
if ( txtOne.Text Xor txtTwo.Text Xor txtThree.Text .....)


http://en.wikipedia.org/wiki/Exclusive_or

look at the truth table, you'll see that Xor is 1 if they are different, applied to everything, that should give 1 if they are all different


quick python example

Code:
jo@Teeshi ~ $ python
Python 2.6.4 (r264:75706, Jan 30 2010, 04:39:02) 
[GCC 4.1.2 (Gentoo 4.1.2 p1.0.1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 <> 2 <> 3 <>4 <> 5 <> 5
False
>>> 1 <> 2 <> 3 <>4 <> 5 <> 6
True
>>> 1 <> 2 <> 3 <>5 <> 5 <> 6
False
>>>

 

bacon

Well-Known Member
It's in C#.net 'cos that's what I code in but I'm sure you can convert it.

Code:
private bool IsValid()
{
    return new[] { textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text, textBox5.Text, textBox6.Text }.Distinct().Count() == 6;
}
 

Juba

In Cryo Sleep
if you want to use a collection class which will only allows unique values in .net you may want to look at hashset class.

Add each text box in turn any duplicate item will result in a false value being returned.

Also do not forget to consider whether duplicate is a case insensitive duplication or not as people often forget that with strings
 

Nanor

Well-Known Member
Followed the advice of BiG D by using nested loops to check it out.

Code:
 For outerIndex As Integer = 0 To 5
                For innerIndex As Integer = 0 To 5
                    If (outerIndex <> innerIndex) Then
                        If lottoNoArray(outerIndex) = lottoNoArray(innerIndex) Then
                            duplicateValue = True
                        End If
                    End If
                Next
            Next

Thanks guys! I'm certain I'll be back with more VB.net banter.
 

Juba

In Cryo Sleep
if you really want to do it that way may I suggest the below as a slightly more efficient way

For outerIndex As Integer = 0 To 4
For innerIndex As Integer = outerIndex+1 To 5
If Array(outerIndex)= Array (innerIndex) Then
duplicateValue = True
End If
Next
Next


requires one less test in the loop and only 10 iterations against the 25 of the original
[/CODE]hmm no idea where the spacing went
 

Silk

Well-Known Member
Sounds like a great place to use collections or lists.

This is C# but it is doable the same way in vb.net (I just don't have that installed at home so can't give the syntax).

6 loops max.

Code:
            bool dups = false;
            IList<String> valChecker = new List<String>();

            for (int i = 0; i < 5; i++)
            {
                if (valChecker.Contains(yourArray[i]))
                {
                    // Already exists..
                    dups = true;
                    break;
                }
                else
                {
                    valChecker.Add(yourArray[i]);
                }
            }

And if you only had the aformentioned textboxes on the form (i.e. no other textboxes), you could even access them directly without having to faff with an array first..

Code:
            bool dups = false;
            IList<String> valChecker = new List<String>();

            foreach (object tb in this.Controls)
	        {
                if (tb is TextBox)
                {
                    TextBox tb2 = (TextBox)tb;
                    if (valChecker.Contains(tb2.Text))
                    {
                        // Already exists..
                        dups = true;
                        break;
                    }
                    else
                    {
                        valChecker.Add(tb2.Text);
                    }   
                }
            }
 

VibroAxe

Junior Administrator
Code:
            bool dups = false;
            IList<String> valChecker = new List<String>();

            foreach (object tb in this.Controls)
	        {
                if (tb is TextBox)
                {
                    TextBox tb2 = (TextBox)tb;
                    if (valChecker.Contains(tb2.Text))
                    {
                        // Already exists..
                        dups = true;
                        break;
                    }
                    else
                    {
                        valChecker.Add(tb2.Text);
                    }   
                }
            }

You could either use the tag property of the textbox of a subset of the name if you really want to do it this way.

Code:
            bool dups = false;
            IList<String> valChecker = new List<String>();

            foreach (object tb in this.Controls)
	        {
                if (tb is TextBox && tb.Name.StartsWith("check"))
//or
//              if (tb is TextBox && tb.tag == "Checkable")
                {
                    TextBox tb2 = (TextBox)tb;
                    if (valChecker.Contains(tb2.Text))
                    {
                        // Already exists..
                        dups = true;
                        break;
                    }
                    else
                    {
                        valChecker.Add(tb2.Text);
                    }   
                }
            }

If you're in C# you can also use linq to pull out all the textboxes in the form, but Bacon is better at linq than me!

Edit: Caveat, without having VS on my phone, it's possible that tb.Name.StartsWith(string) is not the correct syntax, but you get the gist
 

Silk

Well-Known Member
Didn't mean to imply there wasn't a way to only get the relevant text boxes, was just keeping it simple, on the offchance he only has to worry about those six! :)

If I recall it's Textbox.Name.Contains("PartOfYourName"), should you wish to only include specific ones.
 

Juba

In Cryo Sleep
Of course if you wanted to be really fancy you wouldnt let them enter duplicates in the first place by implementing gain focus handlers for the text box and lose focus handlers which checked for duplicates and told them off :)
 

Silk

Well-Known Member
From my experience users prefer validation done on a button press, otherwise it can be irritating :)
 

Juba

In Cryo Sleep
Well it depends on the application to a certain extent and what the contents of the app are none of which we currently know :)
 

Wol

In Cryo Sleep
I'd much prefer to have something that said as I go along whether something was invalid, like it puts a giant red X next to the box going "duplicate value", rather than submitting a form and then being told that it's wrong and having to scroll back.

Well it depends on the application to a certain extent and what the contents of the app are none of which we currently know :)

Which goes back to the age old document of "How to correctly ask a question"...
 

Juba

In Cryo Sleep
Indeed the op told us next to nothing about the context so it is hard to determine the best approach
 

BiG D

Administrator
Staff member
He said it was an assignment for college, so go ahead and assume it's all completely arbitrary.
 
Top