2017-02-11 5 views
0

私のコードは以下の通りです。配列Aの最初の値がAの他のすべての値と同じ場合は、いくつかの大きなif文をタイプすることでそれを行うことができますが、私はむしろそれをしません。配列内のすべての値が同じであるかどうかを調べる - Visual Basic

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 
+2

まず、これはVBAではなく、VB.NETです.2つの全く異なる言語です。次に、配列の代わりに 'HashSet 'を使用してください。それで '.Contains'を呼び出すことができます。 – Comintern

+0

@Comintern、あなたはポイントを逃している、彼は知っていることを知りたくない..彼はすべての同じ値を知りたい。 –

+0

@Trevor - 「ポイント」は、配列がこのための適切なコンテナではないということです。 LinqはVB.NETで苦しいですが、同等のC#コードは次のようになります: 'a.Count == b.Count && a.All(x => b.Contains(x));' – Comintern

答えて

0

は、アレイをスキャンするための簡単な機能を実行し、事前に

おかげで...

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 
3

質問テキストおよびサンプルコードの間に断線があります。私は両方のオプションに答えます。これは、アレイ内の任意の値が第1の値に一致する可能性がサンプルコードに基づいている:

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 

ザアレイ内全て値が最初に一致しなければならない質問のテキストに基づいています値:

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 
+0

どこの機能を見つけるの?私はAllがsystem.arrayのメンバーではないのですか? –

+1

@ Trevorしかし、これはIEnumerableの拡張メソッドであり、配列は実装されています。 System.Linqをインポートする必要があります。 –

+0

私はすでに何をしていましたか? –

0

FYIここでは、In-ラインスキャン時間のベンチマークテストコードと結果の対私きゅうです。

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 

結果

きゅうがかかった - 平均:23.640000144951分:21.9999812543392最大:36.0004836693406

をスキャン取った - 平均:7.11899993475527分:5.99976629018784最大:9.00027807801962

すべての時間をミリ秒で表します。

覚えておくべきこと..コーディングのショートカット<>コーディングの効率。

+0

私はあなたがこの興味深い@JoelCoehoornを見つけるかもしれないと思った –

+2

一般的にあなたの結果を疑うわけではありません(Linqはiteratorのための状態マシンを維持する上でいくつかのオーバーヘッドを持つことができます)。ベンチマークには 'Now'を使います。代わりに 'System.Diagnostics.Stopwatch'型を使用してください。 「今」はプロセスに重大なエラーを引き起こす可能性があります。 2).NetではJust-In-Timeコンパイルの問題のため、両方の方法でベンチマークを実行し、結果を破棄してから再度実行するか、実行する最初のオプションに大きなペナルティを課す危険があります。 –

+1

もうひとつ考えてみましょう。ベンチマークコードに行くと、linqコードに勝る「通常の」コードを書く方法をいつでも簡単に見つけることができます。しかし、パフォーマンス上の問題を解決するために実際のコードベースを見てみると、私はlinqコードが一般により良いアルゴリズムを最初に使用していたことがわかります...遅延最適化の利点やストリームを利用する可能性がますます高くなりますオブジェクトをすべてメモリにロードするのではなく、これは、プログラマーがオーバーヘッドよりもはるかに重要なより良いパターンに陥るのを助けました。 –

関連する問題