0

My code is below, what I need from the sub quicker is if the first value in the array A is the same as every single other value in A, I could do it by typing out some large if statements but I would rather not do that.

Thanks in advance

Public Function Areas_Of_England_Checker()
    Dim South_East() As System.Drawing.Color = {Oxfordshire.BackColor, Buckinhamshire.BackColor, Berkshire.BackColor, Hampshire.BackColor, Isle_Of_White.BackColor, West_Sussex.BackColor, Kent.BackColor, Surrey.BackColor, London.BackColor}
    Dim South_West() As System.Drawing.Color = {Devon.BackColor, Cornwall.BackColor, Somerset.BackColor, Whiltshire.BackColor, Gloucestershire.BackColor, Dorset.BackColor}
    Dim East_Anglia() As System.Drawing.Color = {Hertfordshire.BackColor, Bedfordshire.BackColor, Cambridgeshire.BackColor, Essex.BackColor, Suffolk.BackColor, Norfolk.BackColor, Northamptonshire.BackColor}
    Dim East_Midlands() As System.Drawing.Color = {Lincolnshire.BackColor, Nottinghamshire.BackColor, Leicestershire.BackColor, Derbyshire.BackColor}
    Dim West_Midlands() As System.Drawing.Color = {Shropshire.BackColor, Staffordshire.BackColor, Herefordshire.BackColor, Worcestershire.BackColor, Warwickshire.BackColor, Cheshire.BackColor}
    Dim North_West() As System.Drawing.Color = {Manchester.BackColor, Merseyside.BackColor, Lancashire.BackColor, Cumbria.BackColor}
    Dim Yorkshire() As System.Drawing.Color = {North_Yorkshire.BackColor, West_Yorkshire.BackColor, South_Yorkshire.BackColor, East_Yorkshire.BackColor}
    Dim North_East() As System.Drawing.Color = {Northumberland.BackColor, County_Durham.BackColor}
    quicker(South_East, 9)
    quicker(South_West, 6)
    quicker(East_Anglia, 7)
    quicker(East_Midlands, 6)
    quicker(North_West, 4)
    quicker(Yorkshire, 4)
    quicker(North_East, 2)
End Function

Public Sub quicker(A As Array, B As Integer)
     If A(0) Is the same as any value in A Then ' sort-of pseudo-code
        resupplytroops += B
    End If
End Sub
7
  • 2
    First, this isn't VBA, it's VB.NET - they're 2 completely different languages. Second, just use HashSet<System.Drawing.Color> instead of arrays. Then you can call .Contains. Commented Feb 11, 2017 at 16:00
  • @Comintern, you're missing the point, he does not want to know Contains.. he wants to know All Same value. Commented Feb 11, 2017 at 16:18
  • @Trevor - The "point" is that an array isn't the right container for this. Linq is painful in VB.NET, but the equivalent C# code would be: a.Count == b.Count && a.All(x => b.Contains(x)); Commented Feb 11, 2017 at 16:23
  • @Cominterm, you need to look at his code again. B is just a value that gets added to some accumulator not an array. Commented Feb 11, 2017 at 16:25
  • 2
    But I'll grant you..he did not ask it very well ;) Commented Feb 11, 2017 at 16:30

3 Answers 3

4

There's a disconnection between the question text and the sample code. I'll answer both options. This is based on the sample code, where any value in the array could match the first value:

Public Sub quicker(A() As System.Drawing.Color, B As Integer)
    ' If A(0) Is the same as any other value in A 
    If A.Skip(1).Any(Function(i) i.Equals(A(0))) Then
        resupplytroops += B
    End If
End Sub

The is based on the question text, where all the values in the array must match the first value:

Public Sub quicker(A() As System.Drawing.Color, B As Integer)
    If A.All(Function(i) i.Equals(A(0))) Then
        resupplytroops += B
    End If
End Sub
Sign up to request clarification or add additional context in comments.

11 Comments

Where u finding those functions ? I get All is not a member of system.array?
@Trevor But it is an extension method on IEnumerable, which arrays implement. You'll need to import System.Linq.
I see the problem... he just used "Array" for the type instead of the actual array type of the items. See my updated code.
:) HA.. that did it
@Joel Coehoorn Linq works in VB.NET? wow, any restrictions or is VB.NET an equal Linq citizen of C#?
|
0

Do a quick function to scan through the array...

Public Sub quicker(A As Array, B As Integer)
    If IsSame(A) Then ' sort-of pseudo-code
        resupplytroops += B
    End If
End Sub

Private Function IsSame(A As Array) As Boolean
    For I as Integer = 1 to A.Length - 1
       If A(I) <> A(0) Then Return False
    Next
    Return True
End Function

Comments

0

FYI Here is my LinQ vs In-Line Scan time benchmark test code and results.

Public Sub LinqVsScanTest()

    Dim A() As System.Drawing.Color
    ReDim A(1000000)
    A.Initialize()
    A(1000000) = Color.Blue
    Dim ST As Double
    Dim MinT As Double = Double.MaxValue
    Dim MaxT As Double = 0
    Dim C As Color = A(0)
    For l = 1 To 1000
        Dim T As Date = Now
        Dim B As Boolean = A.All(Function(i) i = C)
        Dim DT As Double = Delta_MilliSeconds(T, Now)
        ST += DT
        If DT > MaxT Then MaxT = DT
        If DT < MinT Then MinT = DT

    Next
    Debug.Print("LinQ took - Average :" & ST / 1000 & " Min :" & MinT & " Max :" & MaxT)

    ST = 0
    MinT = Double.MaxValue
    MaxT = 0

    For l = 1 To 1000
        Dim T As Date = Now
        Dim B As Boolean = True
        For x As Integer = 1 To A.Length - 1
            If A(x) <> A(0) Then B = False : Exit For
        Next
        Dim DT As Double = Delta_MilliSeconds(T, Now)
        ST += DT
        If DT > MaxT Then MaxT = DT
        If DT < MinT Then MinT = DT

    Next
    Debug.Print("Scan took - Average :" & ST / 1000 & " Min :" & MinT & " Max :" & MaxT)

End Sub

Results

LinQ took - Average :23.640000144951 Min :21.9999812543392 Max :36.0004836693406

Scan took - Average :7.11899993475527 Min :5.99976629018784 Max :9.00027807801962

All times in milliseconds.

Something to remember.. Coding shortcuts <> Coding Efficiency.

6 Comments

I thought you might find this interesting @JoelCoehoorn
Not that I doubt your results in general (Linq can have some overhead in maintaining it's state machine for the iterator), there are some more things here to look at: 1) Don't use Now for benchmarks. Instead use the System.Diagnostics.Stopwatch type. Now can introduce significant error into the process. 2) With .Net, because of Just-In-Time compile issues, you need to run your benchmark both ways, throw away there results, and then run it again, or you risk putting a big penalty on the first option that runs.
Another thought here: when you go to benchmark code, you can pretty much always easily find a way to write "regular" code that beats the linq code. But when I go look at real-world code bases to fix performance problems, I tend to the find that the linq code was using generally better algorithms in the first place... much more likely to take advantage of lazy-optimization benefits or stream objects rather than load them all into memory. It helped programmers fall into better patterns that mattered much more than the overhead.
I agree with both your points @JoelCoehoorn. I see folks posting LINQ answers all the time and was just curious about whether that abbreviated code was really the "best" solution, whatever that is. I thought I had better post my results in case some people were just blindly using it. The truth is, if its only a single level comparison like that, then the overhead is too great because, in addition to the iteration overhead, you are effectively adding one more function call per loop that your really don't need. If your scan loop has to also call a function then the cost is not so bad.
For sorts and searches though, especially with programmers that don't know how to do that efficiently, LINQ is likely the better solution in more cases.@JoelCoehoorn.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.