अगर नक्शे में गो की कुंजी है तो कैसे जांचें?


760

मुझे पता है कि मैं इसके mद्वारा एक नक्शे पर पुनरावृति कर सकता हूं ,

for k, v := range m { ... }

और एक कुंजी के लिए देखो, लेकिन क्या नक्शे में एक कुंजी के अस्तित्व का परीक्षण करने का एक अधिक कुशल तरीका है?

मुझे भाषा युक्ति में उत्तर नहीं मिला ।


2
यहां पर दिए गए लिंक में उत्तर खोजने के लिए यहां देखें: golang.org/ref/spec#Index_expressions
nobar

जवाबों:


1470

एक पंक्ति उत्तर:

if val, ok := dict["foo"]; ok {
    //do something here
}

स्पष्टीकरण:

ifगो में दिए गए बयानों में एक शर्त और एक प्रारंभिक कथन दोनों शामिल हो सकते हैं। उपरोक्त उदाहरण दोनों का उपयोग करता है:

  • दो चर को इनिशियलाइज़ करता है - valया तो मैप से "फू" का मान प्राप्त करेगा या "शून्य मान" (इस स्थिति में रिक्त स्ट्रिंग) और okएक बूल प्राप्त करेगा जो सेट किया जाएगा trueयदि "फू" वास्तव में मानचित्र में मौजूद था

  • मूल्यांकन करता है ok, जो होगा trueअगर "फू" मानचित्र में था

यदि "फू" वास्तव में नक्शे में मौजूद है, तो ifविवरण के निकाय को निष्पादित किया valजाएगा और उस दायरे में स्थानीय होगा।


2
यह बेहतर तरीके से समझाया जा सकता है कि यह कैसे काम करता है (पेट्रो से अन्य टिप्पणी की तरह)
चामुएल बौद्जन

6
@Kiril var val string = ""वही रहेगा, val, ok :=उसी नाम से एक नया स्थानीय वैरिएबल बनाता है जो उस ब्लॉक में केवल विज़िबल है।
OneOfOne

1
महान जवाब, क्या आप कहेंगे कि इसकी जटिलता हे (1) है ??
मिन्नी

1
@ मीनी, मुझे पता है कि मैं यहाँ थोड़ी देर से हूँ, लेकिन इस प्रश्न में जाने में लुकअप जटिलता की चर्चा है। ज्यादातर समय परिशोधन जटिलता O (1) है, लेकिन यह उस प्रश्न के उत्तर को पढ़ने के लायक है।
3ocene

70
अजगर की तुलना में ऐसा भ्रामक वाक्यविन्यास if key in dict
प्रांजल मित्तल

128

के अलावा जाओ प्रोग्रामिंग भाषा विशिष्टता , आप पढ़ना चाहिए प्रभावी जाओनक्शे पर अनुभाग में , वे कहते हैं, अन्य बातों के अलावा:

मानचित्र में मौजूद कुंजी के साथ एक मानचित्र मान प्राप्त करने का प्रयास मानचित्र में प्रविष्टियों के प्रकार के लिए शून्य मान लौटाएगा। उदाहरण के लिए, यदि मानचित्र में पूर्णांक होते हैं, तो एक गैर-मौजूद कुंजी को देखना होगा। 0. एक सेट को मूल्य प्रकार बूल के साथ एक मानचित्र के रूप में लागू किया जा सकता है। सेट में मूल्य डालने के लिए मानचित्र प्रविष्टि को सही पर सेट करें, और फिर इसे सरल अनुक्रमण द्वारा परीक्षण करें।

attended := map[string]bool{
    "Ann": true,
    "Joe": true,
    ...
}

if attended[person] { // will be false if person is not in the map
    fmt.Println(person, "was at the meeting")
}

कभी-कभी आपको एक शून्य मान से लापता प्रविष्टि को भेद करने की आवश्यकता होती है। क्या "UTC" के लिए कोई प्रविष्टि है या यह 0 है क्योंकि यह मानचित्र में बिल्कुल भी नहीं है? आप एक से अधिक असाइनमेंट के साथ भेदभाव कर सकते हैं।

var seconds int
var ok bool
seconds, ok = timeZone[tz]

स्पष्ट कारणों के लिए इसे "अल्पविराम" मुहावरा कहा जाता है। इस उदाहरण में, यदि tz मौजूद है, तो सेकंड्स उचित रूप से सेट हो जाएंगे और ok सही हो जाएगा; यदि नहीं, तो सेकंड शून्य पर सेट हो जाएंगे और ओके गलत होगा। यहाँ एक फ़ंक्शन है जो इसे एक अच्छी त्रुटि रिपोर्ट के साथ रखता है:

func offset(tz string) int {
    if seconds, ok := timeZone[tz]; ok {
        return seconds
    }
    log.Println("unknown time zone:", tz)
    return 0
}

वास्तविक मूल्य के बारे में चिंता किए बिना मानचित्र में उपस्थिति के लिए परीक्षण करने के लिए, आप मूल्य के लिए सामान्य चर के स्थान पर रिक्त पहचानकर्ता (_) का उपयोग कर सकते हैं।

_, present := timeZone[tz]

57

पर खोज की जाने पागल ईमेल सूची और एक समाधान पीटर Froehlich द्वारा 2009/11/15 पर पोस्ट पाया।

package main

import "fmt"

func main() {
        dict := map[string]int {"foo" : 1, "bar" : 2}
        value, ok := dict["baz"]
        if ok {
                fmt.Println("value: ", value)
        } else {
                fmt.Println("key not found")
        }
}

या, अधिक कॉम्पैक्ट रूप से,

if value, ok := dict["baz"]; ok {
    fmt.Println("value: ", value)
} else {
    fmt.Println("key not found")
}

ध्यान दें, ifबयान के इस रूप का उपयोग करते हुए, valueऔर okचर केवल ifस्थितियों के अंदर दिखाई देते हैं।


20
यदि आप वास्तव में केवल इस बात में रुचि रखते हैं कि कुंजी मौजूद है या नहीं, और मूल्य की परवाह नहीं है, तो आप उपयोग कर सकते हैं _, ok := dict["baz"]; ok_भाग एक अस्थायी चर बनाने के दूर मूल्य फेंकता बजाय।
मैथ्यू क्रुमले

26

संक्षिप्त जवाब

_, exists := timeZone[tz]    // Just checks for key existence
val, exists := timeZone[tz]  // Checks for key existence and retrieves the value

उदाहरण

यहाँ गो प्लेग्राउंड में एक उदाहरण दिया गया है

दीर्घ उत्तर

प्रभावी गो के मानचित्र अनुभाग के अनुसार :

मानचित्र में मौजूद कुंजी के साथ एक मानचित्र मान प्राप्त करने का प्रयास मानचित्र में प्रविष्टियों के प्रकार के लिए शून्य मान लौटाएगा। उदाहरण के लिए, यदि मानचित्र में पूर्णांक होते हैं, तो एक गैर-मौजूद कुंजी को देखना 0 पर लौटेगा।

कभी-कभी आपको एक शून्य मान से लापता प्रविष्टि को भेद करने की आवश्यकता होती है। क्या "UTC" के लिए कोई प्रविष्टि है या खाली स्ट्रिंग है क्योंकि यह मानचित्र में बिल्कुल भी नहीं है? आप एक से अधिक असाइनमेंट के साथ भेदभाव कर सकते हैं।

var seconds int
var ok bool
seconds, ok = timeZone[tz]

स्पष्ट कारणों के लिए इसे "अल्पविराम" मुहावरा कहा जाता है। इस उदाहरण में, यदि tz मौजूद है, तो सेकंड्स उचित रूप से सेट हो जाएंगे और ok सही हो जाएगा; यदि नहीं, तो सेकंड शून्य पर सेट हो जाएंगे और ओके गलत होगा। यहाँ एक फ़ंक्शन है जो इसे एक अच्छी त्रुटि रिपोर्ट के साथ रखता है:

func offset(tz string) int {
    if seconds, ok := timeZone[tz]; ok {
        return seconds
    }
    log.Println("unknown time zone:", tz)
    return 0
}

वास्तविक मूल्य के बारे में चिंता किए बिना मानचित्र में उपस्थिति के लिए परीक्षण करने के लिए, आप मूल्य के लिए सामान्य चर के स्थान पर रिक्त पहचानकर्ता (_) का उपयोग कर सकते हैं।

_, present := timeZone[tz]

13

जैसा कि अन्य उत्तरों से पता चलता है, सामान्य समाधान विशेष रूप के असाइनमेंट में एक इंडेक्स एक्सप्रेशन का उपयोग करना है:

v, ok = a[x]
v, ok := a[x]
var v, ok = a[x]
var v, ok T = a[x]

यह अच्छा और साफ है। हालांकि इसके कुछ प्रतिबंध हैं: यह विशेष रूप का एक असाइनमेंट होना चाहिए। राइट-हैंड साइड एक्सप्रेशन केवल मैप इंडेक्स एक्सप्रेशन होना चाहिए, और लेफ्ट-हैंड एक्सप्रेशन लिस्ट में बिल्कुल 2 ऑपरेंड होने चाहिए, जिसमें से पहला मान टाइप असाइन करने योग्य है, और दूसरा जिसके लिए boolवैल्यू असाइन करने योग्य है। इस विशेष फॉर्म के परिणाम का पहला मूल्य कुंजी के साथ जुड़ा मूल्य होगा, और दूसरा मूल्य बताएगा कि क्या वास्तव में दिए गए कुंजी के साथ नक्शे में एक प्रविष्टि है (यदि कुंजी नक्शे में मौजूद है)। यदि परिणाम की आवश्यकता नहीं है, तो बाएं हाथ की अभिव्यक्ति सूची में रिक्त पहचानकर्ता भी हो सकता है ।

यह जानना महत्वपूर्ण है कि यदि अनुक्रमित मानचित्र मान nilमें कुंजी है या नहीं है, तो सूचकांक अभिव्यक्ति मानचित्र के मूल्य प्रकार के शून्य मान का मूल्यांकन करता है । उदाहरण के लिए:

m := map[int]string{}
s := m[1] // s will be the empty string ""
var m2 map[int]float64 // m2 is nil!
f := m2[2] // f will be 0.0

fmt.Printf("%q %f", s, f) // Prints: "" 0.000000

इसे गो प्ले ग्राउंड पर आज़माएं ।

इसलिए यदि हम जानते हैं कि हम अपने मानचित्र में शून्य मान का उपयोग नहीं करते हैं, तो हम इसका लाभ उठा सकते हैं।

उदाहरण के लिए यदि मान प्रकार है string, और हम जानते हैं कि हम उन मानचित्रों में प्रविष्टियाँ संग्रहीत नहीं करते हैं जहाँ मान रिक्त स्ट्रिंग ( stringप्रकार के लिए शून्य मान ) है, तो हम यह भी परीक्षण कर सकते हैं कि क्या कुंजी गैर-विशेष की तुलना करके मानचित्र में है शून्य मान के लिए अनुक्रमणिका अभिव्यक्ति का परिणाम ()

m := map[int]string{
    0: "zero",
    1: "one",
}

fmt.Printf("Key 0 exists: %t\nKey 1 exists: %t\nKey 2 exists: %t",
    m[0] != "", m[1] != "", m[2] != "")

आउटपुट (इसे खेल के मैदान पर आज़माएं ):

Key 0 exists: true
Key 1 exists: true
Key 2 exists: false

व्यवहार में ऐसे कई मामले हैं जहाँ हम मानचित्र में शून्य-मान को संग्रहीत नहीं करते हैं, इसलिए इसका उपयोग अक्सर किया जा सकता है। उदाहरण के लिए इंटरफेस और फ़ंक्शन प्रकार का शून्य मान होता है nil, जिसे हम अक्सर मानचित्र में संग्रहीत नहीं करते हैं। इसलिए यदि मानचित्र में कोई कुंजी है, तो उसकी तुलना करके परीक्षण किया जा सकता है nil

इस "तकनीक" का उपयोग करने का एक और फायदा भी है: आप कई कुंजियों के अस्तित्व को एक कॉम्पैक्ट तरीके से देख सकते हैं (आप ऐसा विशेष "अल्पविराम" के रूप में नहीं कर सकते हैं)। इसके बारे में अधिक जानकारी: जांचें कि क्या कुंजी एक स्थिति में कई मानचित्रों में मौजूद है

गैर-मौजूदा कुंजी के साथ अनुक्रमण करते समय मूल्य प्रकार का शून्य मान प्राप्त करना भी हमें सेट केbool रूप में मूल्यों के साथ नक्शे का उपयोग करने की अनुमति देता है । उदाहरण के लिए:

set := map[string]bool{
    "one": true,
    "two": true,
}

fmt.Println("Contains 'one':", set["one"])

if set["two"] {
    fmt.Println("'two' is in the set")
}
if !set["three"] {
    fmt.Println("'three' is not in the set")
}

यह आउटपुट (इसे खेल के मैदान पर आज़माएं ):

Contains 'one': true
'two' is in the set
'three' is not in the set

संबंधित देखें: मैं एक सरणी कैसे बना सकता हूं जिसमें अद्वितीय तार शामिल हैं?


1
क्या है Tमें var v, ok T = a[x]? okबूल नहीं होना चाहिए?
कोकिज्जु

2
@Kokizzu यह चर घोषणा का सामान्य रूप है। पहले हम सोच सकते हैं कि यह केवल काम करेगा (संकलित) यदि नक्शा प्रकार का होगा map[bool]boolऔर Tहै bool, लेकिन यह भी काम करता है यदि नक्शा प्रकार का है map[interface{}]boolऔर Tहै interface{}; इसके अलावा यह भी boolअंतर्निहित प्रकार के रूप में होने वाले कस्टम प्रकारों के साथ काम करता है , गो प्लेग्राउंड पर सभी देखें । इसलिए चूंकि यह फॉर्म कई प्रकारों के लिए मान्य है T, जिसके लिए सामान्य Tका उपयोग किया जाता है। प्रकार okकुछ भी हो सकता है जिसके लिए एक अनकैप्डbool सौंपा जा सकता है।
icza


4
    var d map[string]string
    value, ok := d["key"]
    if ok {
        fmt.Println("Key Present ", value)
    } else {
        fmt.Println(" Key Not Present ")
    }

3
    var empty struct{}
    var ok bool
    var m map[string]struct{}
    m = make(map[string]struct{})
    m["somestring"] = empty


    _, ok = m["somestring"]
    fmt.Println("somestring exists?", ok) 
    _, ok = m["not"]
    fmt.Println("not exists?", ok)

तो फिर, चलाने के लिए maps.go somestring मौजूद है? सच मौजूद नहीं है? असत्य


इंट की जरूरत से छुटकारा
दिलाता है

योगदान के लिए धन्यवाद, लेकिन मुझे लगता है कि वर्तमान उत्तर प्रश्न को अच्छी तरह से कवर करते हैं। यहाँ आप जो कह रहे हैं, उससे आपका उत्तर गो प्रकार के प्रश्नों के सेट को लागू करने का एक सर्वोत्तम तरीका होगा ।
tomasz

_, ok = m["somestring"]होना चाहिए=_, ok := m["somestring"]
एलारॉय जेटसन

3

इसका उल्लेख "इंडेक्स एक्सप्रेशंस" के तहत किया गया है ।

एक मानचित्र पर एक अनुक्रमणिका अभिव्यक्ति एक प्रकार का नक्शा [के] वी है जो विशेष रूप के असाइनमेंट या आरंभीकरण में उपयोग किया जाता है

v, ok = a[x] 
v, ok := a[x] 
var v, ok = a[x]

एक अतिरिक्त बेक्ड बूलियन मूल्य देता है। यदि मानचित्र में कुंजी x मौजूद है और अन्यथा गलत है तो ok का मान सत्य है।


1

इस उद्देश्य के लिए एक दो मूल्य असाइनमेंट का उपयोग किया जा सकता है। कृपया नीचे मेरा नमूना कार्यक्रम देखें

package main

import (
    "fmt"
)

func main() {
    //creating a map with 3 key-value pairs
    sampleMap := map[string]int{"key1": 100, "key2": 500, "key3": 999}
    //A two value assignment can be used to check existence of a key.
    value, isKeyPresent := sampleMap["key2"]
    //isKeyPresent will be true if key present in sampleMap
    if isKeyPresent {
        //key exist
        fmt.Println("key present, value =  ", value)
    } else {
        //key does not exist
        fmt.Println("key does not exist")
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.