2011-07-09 5 views
0

可能性の重複さ:
Scala map containing mix type valuesScalaの同じタイプのキーでマップが、値の値およびサブタイプのための不規則なタイプと自身が不規則

私は、以前のグルーヴィーの状況を持っていますプログラムは次のような構造を構築しています。

mp = [k1: "string", k2: [d1: [1,2,3], d2: 1975], k3: 345, k4: ["one","two"]] 

to:

[String: String, String: Map[String, Any], String: Int, String: List[String]] 

この関数は、呼び出し関数にmpを返します。

あなたがmpマップの値が不規則であることがわかるように。私はスカラでプログラムを書き直しています。

scalaでは、mpをMap [String、Any]として表現する必要がありますが、mpを使用するテストコードではisInstanceOfとasInstanceOfでダンスを演奏します。その結果、多くのスカラー定型文が生成されます。 ScalaがList [String]をAnyにキャストすることができないという不満の主な理由は、例えばAnyにキャストできません。

スカラーには優れたソリューションがありますか?

もっと慎重に見ると、この質問は前の質問とは異なります。この質問では、キーk2の値[d1:[1,2,3]、d2: "string"]がそれ自体が不規則なマップであることがわかります。

私は、このソリューションを提案しました: のような他のScalaのクラスを作成します。テストコードで

class MakeMap { 

// lot of code here 
.... 

val k1: String = // put here value found in logic above 
val k2 : Map[String, Any] // here is the issue, I am again forced to use Any 
val k3 : List[String] // put here value found in logic above 

} 

:Scalaのユーザーに

val m1 = new MakeMap() 
m1.k1 // very easy to access value, also gets rid of scala verbose syntax to access vale 
     // in map like getOrElse 
m1.k2 // this is the issue, it seesm I have to define yet another class 
m1.k3 // again easy 
+2

この質問と[あなたの前の質問]の違いは何ですか(http://stackoverflow.com/q/6584840/390581)?ちなみに、あなたは、異なるタイプの*値*を意味します。あなたの鍵はすべて弦であるようです。 –

+0

あなたはList [String]を任意のものに変換できるので、エラーメッセージを投稿してください...あなたがScalaでより良いソリューションを望むなら、Javaまたは動的言語からソリューションを直接移譲するのを止めなければなりません。キーと値の制約について詳しく述べると、Scalaの適切なソリューションを見つけるのに役立つかもしれません。 – paradigmatic

+0

申し訳ありませんこれは私の以前の質問に似ていることを認識していませんでした。私は別の文脈を見ているときにこの質問をしています。この質問を削除してください。私の脳はスカラーによって部分的に傷ついています:) – rjc

答えて

1

コードをGroovyからScalaに書き直す場合は、パフォーマンスと安全性を求めていると思います。だから両方を失う可能性があるので、地図を使ってすべてを保管しないようにしてください。必要なデータ構造をあらかじめ定義しておき、変更可能な構造体と見なすことができるcase classを使用してください。例えば

、Groovyの値の同等:

val mp = Outer("string", Inner(List(1,2,3), 1975), 345, List("one","two")) 

そして:次に、あなたのようにあなたのオブジェクトmpを作成することができ

case class Outer(k1: String, k2: Inner, k3: Int, k4: List[String]) 
case class Inner(d1: List[Int], d2: Int) 

[k1: "string", k2: [d1: [1,2,3], d2: 1975], k3: 345, k4: ["one","two"]] 

のように定義することができます。アクセスメンバー:

val x = mp.k2.d2

もちろん、わかりやすい名前を付けてください。まず、できるだけ型を制限し、Any,AnyRefまたはAnyValを避けてください。それはしばしば可能です。

+0

ケースクラスは素晴らしい解決策のように見えますが、私のケースでは理解しようとしていることの1つは、他のパラメータを計算するために使用されるケースクラスにパラメータを渡す必要があり、ケースクラスがパブリックを計算するために使用するロジックですクラスメンバー。あなたのコードでは、呼び出し側がcaseクラスに渡す値を知っているように見え、caseクラスはval x = mp.k2.d2のようにアクセスするときにこれらの値を返すだけです。私の場合、呼び出し元はcaseクラスに渡す値について何も知らない。 – rjc

+0

私は現在、ケースクラスの理解を深めていると思います。私は現在、戻り値の型を実際に多くのビジネスロジックを行う関数のcaseクラスにしています。 – rjc

+0

はい。すべてのフィールドを返す前にすべてのフィールドを計算するファクトリメソッドで、caseクラスを構築しようとします。 – paradigmatic

2

Thisメッセージは、あなたがしているユースケースに対処するようですに興味がある?

関連する問題