2013-04-17 4 views
14

Scalaでは、大きさ(またはそれ以下)または特定の値に等しいリストに一致するパターンを指定する方法はありますか?例えば特定のサイズ以上のパターンマッチングリスト

、私はサイズが3以下のすべてのリストに同じアクションを適用する場合:

list match { 
    case Nil => op(list) 
    case x :: Nil => op(list) 
    case x :: y :: Nil => op(list) 
    case x :: y :: z :: Nil => op(list) 
    case x :: tail => other(list) 
} 

2例にこれを削減する方法はありますか?

+0

は私が...それはガードで行うことができます...場合を考える(tail.size> = x)は=> – Dan

答えて

11

はい、あなたは例の順序を逆にする必要がありますが、私はパターンではなく、listを参照リストに新しい変数lを束縛し、そのまし

list match { 
    case l @ (_ :: _ :: _ :: _) => other(l) 
    case l => op(l) 
} 

注意私は変数が必要ないときは_を使用しました。私はこれらの習慣の両方に固執することをお勧めしますが、その答えはそれらがなければまったく同じに働くでしょう。

+1

私は、このような難読化された構文を使用してのポイントが表示されないときのガード条件の場合仕事は質問で尋ねられますか? –

+1

@DenisR .:まず、尋ねられたように質問に答えていました。そして、第二に、長さが高価な操作であるリストを使って作業しているとき、この答えが実際にガード条件よりも慣れないことはわかりません。リストをトラバースするのを避けたいのであれば、 'l.lengthCompare(3)> -1'のような' case l 'のようなものを書く必要があります。 –

+1

あなたは複雑さとlengthCompareの使用について正しいです。 長さが明示的に書かれていて、 "_" -1の数で書かれていないので、私はこの解決策を好む。 あなたの説明をありがとう。 –

6

普通の古いif/wrongの何が問題ですか?

list.splitAt(len) match { 
    case (xs, Nil) => other(xs) 
    case (_, _) => op(list) 
} 

はまた複雑リストが長い場合は、 len因子を決定されるため、場合でも O(len)です:

if (list.length >= minimumLength) 
    longer(list) 
else 
    shorter(list) 
+1

リストが本当に長い場合はどうなりますか?長さを使用しないでマッチ/ケースは良いでしょう... – huynhjl

+5

良い点。この場合、 'lengthCompare'を使うことができます。 –

+0

「本当に長い」ものは何か分かりませんが、リストは保持される要素ごとにかなりのサイズのオーバーヘッドを持ち、非常に大きなコレクションでは強く示されません。彼らは本当に1つの大きな美徳しか持っていません。非常に効率的な頭/尾の分解です。 –

4

はまたでそれを行うことができます。

上記通話oplist.size < lenは、あなたが(多分あなたはより多くのマッチケースを含めたい?)パターンマッチを使用して主張する場合、あなたはそれのためにガード条件を使用することができますother

10

を呼び出す場合:

list match { 
    case l if(l.size <= 3) => op(l) 
    case l => other(l) 
} 
+2

lengthCompareを使用すると、リストの長さを3と比較する方が効率的です –