2013-01-07 24 views
31

Verilen bir haritada belirli bir anahtarı bulmak istiyorum. Anahtar bulunursa, o zaman bu anahtarın değerini haritadan almak istiyorum.groovy: bir harita içinde bir anahtar bulup değerini dön

Bu defa yönetilen şudur: beklendiği gibi

Bu işleri
def mymap = [name:"Gromit", likes:"cheese", id:1234] 

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

if(x) 
    println x.value 

, çıkış "peynir" dir. Harika, ama sonunda x.value yapmak istemiyorum ve if(x) yapmak istemiyorum. Ben bir şekilde değeri bir şekilde doğrudan içermek istiyorum.

böyle doğrudan x içine değeri elde edemez: bulmak kapatma bu durumda null

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

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

println x 

Çünkü bu bir boş gösterici hariç sonuçlanır. Elbette, yukarıdaki kod snippet'i it.key == "likes" olduğunda çalışır, ancak her zaman hedef anahtarın haritada bulunacağından emin değilim. Bir harita belirli bir tuşa

  • Ve eğer öyleyse sahiptir

    • Kontrol eğer bu tuş
    • değerini almak: bir harita üzerinde bunu yapmak için "Groovier" ve güvenli yolu nedir

  • cevap

    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 
    

    ?. çek ve Groovy bir istisna oluşturmaz: deneyin. Anahtar yoksa, sonuç bir org.codehaus.groovy.runtime.NullObject olacaktır.

    +0

    Müthiş. Bu, seçtiğim orijinal cevaptan bile daha iyi ve aradığımı daha iyi uyuyor. Bunu işaretlemek cevaptır. Teşekkürler. – noumenon

    +3

    Bir kapak kullanımı çok pahalı. Daha iyi kullanın 'def x = mymap.get (" beğeni ") ?. değeri var, o daha verimli –

    46

    Haritalar'ı kullanmanın tüm noktası doğrudan erişimdir. Bir haritanın değer Groovy- false asla kesin olarak biliyorsanız, o zaman bunu yapabilirsiniz:

    def mymap = [name:"Gromit", likes:"cheese", id:1234] 
    def key = "likes" 
    
    if(mymap[key]) { 
        println mymap[key] 
    } 
    

    Ancak, değer potansiyel Groovy- false olabilir, sen kullanmalısınız:

    Eğer değer (veya göz ardı edilebilir) false Groovy- olacak değil biliyorum ve bir varsayılan değer istiyorsanız
    if(mymap.containsKey(key)) { 
        println mymap[key] 
    } 
    

    kolay çözüm olsa da, bu gibi:

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

    Bu çözümlerin üçü örneklerden çok daha hızlıdır çünkü tüm haritayı anahtarlar için taramazlar. Doğrudan anahtar erişimini neredeyse anında yapan HashMap (veya LinkedHashMap) tasarımından yararlanırlar.

    +1

    teşekkür ederiz. Tamamen noktayı kaçırıyordum. – noumenon

    +1

    Varsayılan değerler istiyorsanız, haritayı 'def map = [:] olarak tanımlayabilirsiniz. WithDefault {"Default"} '. Daha sonra, varsayılan değer için Elvis Operatörünü kullanmanız gerekmez. Tabii ki, bu haritayı da güncelleyecektir, eğer istemiyorsan, o zaman Elvis senin yolun. – fish

    +0

    Anahtar çift tırnak ile de belirtilebilir, örneğin \t \t def başlıkları = ["Content-Type": "application/json"] – webjockey

    0

    Null Pointer Exception'ı kullanmanızın nedeni, ikinci örneğinizdeZZZ anahtar anahtarının olmamasıdır. Boş için

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

    Soruda belirtildiği gibi, anahtarın her zaman harita, bu yüzden anahtarın haritada olmasa bile güvenli bir şekilde (istisnasız) çalışmasını istedim. – noumenon

    1

    Genel olarak, haritanızın içeriğine göre değişir. Eğer null değerlere sahipse, işler gerçekten zor olabilir ve elemanın gerçekten varlığını tespit etmek için containsKey(key) veya get(key, default) kullanılmalıdır. Birçok durumda kod varsayılan bir değer tanımlayabilirsiniz basit hale gelebilir: Ayrıca

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

    Not o containsKey() veya get() elemanı mymap.find{ it.key == "likes" } kontrol etmek için bir kapatma kurma çok daha hızlıdır.Kapatma kullanmak sadece gerçekten daha karmaşık bir şey yaparsanız mantıklıdır. Ör. Bunu yapmak:

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

    Veya açık parametrelerle:

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