2013-01-07 3 views
31

特定のマップ内の特定のキーを検索したいと思います。キーが見つかった場合は、そのキーの値をマップから取得します。groovy:マップ内のキーを見つけてその値を返します

これは私がこれまで管理するものである:

def mymap = [name:"Gromit", likes:"cheese", id:1234] 

def x = mymap.find{ it.key == "likes" } 

if(x) 
    println x.value 

この作品予想通り、出力は「チーズ」です。素晴らしいですが、最後にx.valueをしたくないので、やりたくありません。if(x)。私はxに何らかの形で直接値を入れたいと思っています。

私はこのようなXに直接値を取得することはできません:検索の閉鎖は、この場合にはnullであるので

def mymap = [name:"Gromit", likes:"cheese", id:1234] 

def x = mymap.find{ it.key == "likesZZZ" }.value 

println x 

、これはNULLポインタ例外になります。もちろん、上記のコードスニペットはit.key == "likes"のときに機能しますが、マップ内でターゲットキーが見つかるかどうかはわかりません。マップ上でこれを行うには、「Groovier」と安全な方法は何

  • チェックマップが与えられたキー、
  • があり、もしそうなら、このキー
  • の値を取得する場合

答えて

10
def mymap = [name:"Gromit", id:1234] 
def x = mymap.find{ it.key == "likes" }?.value 
if(x) 
    println "x value: ${x}" 

println x.getClass().name 

?.チェックやGroovyで例外を作成しません:試してみてください。キーが存在しない場合、結果はorg.codehaus.groovy.runtime.NullObjectになります。

+0

これは私が選んだオリジナルの答えよりも面白くて、私が探していたものによく合います。これを印は答えです。ありがとう。 – noumenon

+3

クロージャを使用すると非常に高価です。 'def x = mymap.get(" likes ")?. value'を使う方がずっと効率的です –

46

マップを使用することの全ポイントは直接アクセスです。値が潜在的にGroovy- falseことができれば

def mymap = [name:"Gromit", likes:"cheese", id:1234] 
def key = "likes" 

if(mymap[key]) { 
    println mymap[key] 
} 

しかし、あなたが使用する必要があります:

あなたがマップ内の値はGroovy- falseになることはありませんことを確実に知る場合は、これを行うことができます、あなたが知っていれば
if(mymap.containsKey(key)) { 
    println mymap[key] 
} 

最も簡単な解決策は、しかし、値がGroovy- falseになるだろうされていない(またはあなたはそれを無視することができる)、およびデフォルト値をしたい、このようなものです:

def value = mymap[key] ?: "default" 

これらの3つのソリューションはすべて、キーのマップ全体をスキャンしないため、サンプルよりも大幅に高速です。彼らはHashMap(またはLinkedHashMap)の設計を利用して、ダイレクトなキーアクセスをほぼ即座に実現します。

+1

おかげでこれを行います。私は完全にポイントを逃していた。 – noumenon

+1

デフォルト値が必要な場合は、マップを 'def map = [:]。withDefault {" Default "}'として定義することができます。次に、デフォルト値としてElvis Operatorを使用する必要はありません。もちろん、これもマップを更新するので、あなたがそれを望まないなら、エルヴィスはあなたの方法です。 – fish

+0

キーは二重引用符でも引用できます。たとえば、\t \t def headerers = ["Content-Type": "application/json"] – webjockey

0

2番目の例でキーlikesZZZが存在しないため、NULLポインタ例外が発生するのは、理由です。ヌルのため

def mymap = [name:"Gromit", likes:"cheese", id:1234] 
def x = mymap.find{ it.key == "likes" }.value 
if(x) 
    println "x value: ${x}" 
+0

質問に記載されているように、キーが常にマップがあったとしても、(例外なく)安全に動作する方法が必要でした。 – noumenon

1

一般に、これはマップに含まれるものによって異なります。それがヌル値を持つ場合、物事が厄介になる可能性があり、実際に存在する要素を検出するためにcontainsKey(key)またはget(key, default)を使用する必要があります。 containsKey()またはget()要素mymap.find{ it.key == "likes" }をチェックするために閉鎖を設定するよりもはるかに高速であることをも

def mymap = [name:"Gromit", likes:"cheese", id:1234] 
def x1 = mymap.get('likes', '[nothing specified]') 
println "x value: ${x}" } 

注:多くの場合、コードを使用すると、デフォルト値を定義することができます簡単になることができます。クロージャを使用することは、実際にはもっと複雑なことを行う場合にのみ意味があります。たとえば、

mymap.find{ // "it" is the default parameter 
    if (it.key != "likes") return false 
    println "x value: ${it.value}" 
    return true // stop searching 
} 

または明示的なパラメータを持つ:

mymap.find{ key,value -> 
    (key != "likes") return false 
    println "x value: ${value}" 
    return true // stop searching 
} 
関連する問題