2017-05-19 10 views
2

私が解決しようとしているCodilityのGenomicRangeQueryスカラ座と私は次の関数を書いたそのために使用した:Scalaは変換IndexedSeq [AnyVal] Arrayに[INT]

def solution(s: String, p: Array[Int], q: Array[Int]): Array[Int] = { 
    for (i <- p.indices) yield { 
    val gen = s.substring(p(i), q(i) + 1) 
    if (gen.contains('A')) 1 
    else if (gen.contains('C')) 2 
    else if (gen.contains('G')) 3 
    else if (gen.contains('T')) 4 
    } 
} 

を私は多くのテストを行っていないがしかし、それは問題を解決するようです。

私の問題はscala.collection.immutable.IndexedSeq[AnyVal]を返しますが、関数はArray[Int]を返さなければならないので、type mismatch errorを投げます。

補題をArray [Int]に戻す方法がありますか、IndexedSeq[AnyVal]Array[Int]に変換する方法はありますか?

答えて

2

スーニスの答えはほとんどそれをカバーしています。

IndexedSeqArrayに呼び出すと、toArrayというコールが生成されるので、最初のビットはかなり簡単です。 2番目の部分では、if... else...のすべてのケースを削除する可能性のある論理的な分岐があるため、yieldはとUnitの両方の型を返します。その最も近い共通の祖先はAnyValです。

if... else...をパターンマッチングに置き換えた場合、可能な限りすべてのコードをキャッチしていないため、コンパイラの警告が表示されることに注意してください。

gen match { case _ if gen.contains("A") => 1 case _ if gen.contains("C") => 2 ... // Throws warning unless you include a `case _ =>` with no `if` clause }

+0

ありがとうございました。デフォルトのケースを追加する必要はありませんでした。 – Micho

+0

"可能性のあるすべてのケースをキャッチしていないため、コンパイラの警告が明示的に表示されます。これは、 'sealed'型の値をマッチさせ、マッチ式内のガードを使用すると、この場合でも警告を無効にする場合にのみ発生します。 –

+0

ああ、是非、訂正してくれてありがとう – Mycleung

1
def solution(s: String, p: Array[Int], q: Array[Int]): Array[Int] = { 
    (for (i <- p.indices) yield { 
    val gen = s.substring(p(i), q(i) + 1) 
    if (gen.contains('A')) 1 
    else if (gen.contains('C')) 2 
    else if (gen.contains('G')) 3 
    else 4 
    }).toArray 
} 

ifステートメントの問題は、既定値がないことです。そのため、IntではなくIndexedSeqが得られます。

+0

toArray'はまだ 'アレイ[INT]' – Micho

+0

@Michoは、デフォルトのケースを処理するために、他を追加するには、[配列を返します一致しない 'アレイ[AnyVal]'、へ戻り値の型をオン '呼び出しますInt]。 OPのオリジナルのコードは、彼がすべての潜在的なケースをカバーしているわけではないので、 – sheunis

2

ここでは2つの問題があります。最初はp.indicesで、Arrayの代わりにscala.collection.immutable.Rangeを返します。 p.indices.toArray(または最後に@sheunisのように.toArrayを追加する)を実行すると問題が解決されます。

その他の問題は、if文が不完全であることに起因します。すべての条件がfalseの場合、メソッドは(): Unit(コンパイラによって追加されたもの)を返します。最後のステートメントとしてelse -1などのデフォルトのケースを追加すると、この2番目の問題が解決されます。

編集:デフォルトの場合は、追加することはできません場合は、次のように、あなたが例外をスローする可能性:

else { 
    val err = "the input String can only contain the characters ACGT" 
    throw new IllegalArgumentException(err) 
} 

これは、次のプログラマとコード内で何が起こっているのコンパイラの両方を通知します。 throw式のタイプがNothingであるため、(Int, Int, Int, Nothing)の最小上限を計算すると、にルブされた(Int, Int, Int, Unit)とは異なり、Intが正しく生成されます。

+0

入力文字列にはACGTという文字しか含めることができないという問題の前提条件です。 @sheunisの答えで起こるように、 'p。indices.toArray'を呼び出すか、forの理解の後でそれを呼び出すと、戻り値の型が 'Array [AnyVal]'になります。これは 'Array [Int]'と一致しません。 – Micho

+0

私の答えの2番目の部分はなぜ 'Array [AnyVal]'を取得し、それを修正するのかを説明しています。デフォルト値の代わりに編集を参照してください。 – OlivierBlanvillain

関連する問題