it-swarm.asia

كيفية التحقق مما إذا كانت الخريطة تحتوي على مفتاح في Go؟

أعلم أنه يمكنني التكرار على خريطة m بواسطة ،

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

وابحث عن المفتاح ولكن هل هناك طريقة أكثر فاعلية لاختبار وجود المفتاح في الخريطة؟

لم أتمكن من العثور على الإجابة في spec spec .

569
grokus

إجابة سطر واحد:

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

تفسير:

يمكن أن تتضمن عبارات if في Go كلاً من الشرط وبيان التهيئة. المثال أعلاه يستخدم كلا:

  • تهيئة اثنين من المتغيرات - val ستتلقى إما قيمة "foo" من الخريطة أو "قيمة صفرية" (في هذه الحالة السلسلة الفارغة) و ok ستتلقى منطقيًا سيتم تعيينه على true في حالة وجود "foo" بالفعل في الخريطة

  • يقيم ok ، والذي سيكون true إذا كان "foo" في الخريطة

إذا كانت "foo" موجودة بالفعل في الخريطة ، فسيتم تنفيذ نص العبارة if و val ستكون محلية لهذا النطاق.

1082
marketer

تحرير: الإجابة التالية تسبق Go 1. بدءًا من Go 1 ، لم تعد دقيقة/صالحة.


بالإضافة إلى مواصفات لغة برمجة Go ، يجب عليك قراءة الانتقال الفعال . في القسم الموجود على الخرائط كما يقولون ، من بين أشياء أخرى:

"ستؤدي محاولة جلب قيمة خريطة باستخدام مفتاح غير موجود في الخريطة إلى تعطل البرنامج ، ولكن هناك طريقة للقيام بذلك بأمان باستخدام مهمة متعددة."

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

"لاختبار التواجد في الخريطة دون القلق بشأن القيمة الفعلية ، يمكنك استخدام المعرف الفارغ ، الشرطة السفلية البسيطة (_). يمكن تعيين معرف فارغ أو إعلانه بأي قيمة من أي نوع ، مع تجاهل القيمة دون أي ضرر. لاختبار التواجد في خريطة ، استخدم المعرف الفارغ بدلاً من المتغير المعتاد للقيمة. "

_, present := timeZone[tz]
92
peterSO

تم البحث في قائمة البريد الإلكتروني الخاصة بـ go -uts ووجدت حلاً تم إرساله بواسطة Peter Froehlich بتاريخ 11/15/2009.

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.

44
grokus

اجابة قصيرة

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

مثال

إليك مثال في Go Playground .

إجابة أطول

حسب الخرائط قسم الانتقال الفعال :

ستؤدي محاولة جلب قيمة خريطة باستخدام مفتاح غير موجود في الخريطة إلى إرجاع قيمة الصفر لنوع الإدخالات في الخريطة. على سبيل المثال ، إذا كانت الخريطة تحتوي على أعداد صحيحة ، فإن البحث عن مفتاح غير موجود سيعود 0.

في بعض الأحيان تحتاج إلى تمييز إدخال مفقود من قيمة صفرية. هل هناك إدخال لـ "UTC" أو هل هذه السلسلة فارغة لأنها غير موجودة على الخريطة على الإطلاق؟ يمكنك التمييز مع شكل من أشكال مهمة متعددة.

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

لأسباب واضحة يسمى هذا المصطلح "فاصلة موافق". في هذا المثال ، إذا كان tz موجودًا ، فسيتم تعيين الثواني بشكل مناسب وستكون "موافق" صحيحة ؛ إذا لم يكن كذلك ، فسيتم تعيين الثواني على صفر وستكون "موافق" خاطئة. فيما يلي وظيفة تضعها مع تقرير خطأ Nice:

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

لاختبار التواجد في الخريطة دون القلق بشأن القيمة الفعلية ، يمكنك استخدام المعرف الفارغ (_) بدلاً من المتغير المعتاد للقيمة.

_, present := timeZone[tz]
20
Matthew Rankin

كما لاحظت إجابات أخرى ، فإن الحل العام هو استخدام تعبير index في واجب للنموذج الخاص:

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

هذا لطيف ونظيف. لديها بعض القيود على الرغم من: يجب أن يكون إحالة شكل خاص. يجب أن يكون تعبير الجانب الأيمن عبارة عن تعبير فهرس الخريطة فقط ، ويجب أن تحتوي قائمة تعبير الجانب الأيسر على معامَنين بالضبط ، أولًا يكون نوع القيمة قابلاً للتخصيص ، وثانيًا يمكن تعيين قيمة 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

جربه على Go Playground .

لذلك إذا علمنا أننا لا نستخدم القيمة الصفرية في خريطتنا ، فيمكننا الاستفادة من ذلك.

على سبيل المثال ، إذا كان نوع القيمة هو 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] != "")

الإخراج (جربه على Go Playground ):

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

في الممارسة العملية ، هناك العديد من الحالات التي لا نقوم فيها بتخزين قيمة القيمة الصفرية في الخريطة ، لذلك يمكن استخدامها كثيرًا. على سبيل المثال ، يكون للواجهات وأنواع الوظائف قيمة صفرية nil ، والتي غالبًا لا نقوم بتخزينها في الخرائط. لذلك يمكن إجراء اختبار ما إذا كان هناك مفتاح موجود في الخريطة من خلال مقارنته بـ nil.

استخدام هذه "التقنية" له ميزة أخرى أيضًا: يمكنك التحقق من وجود مفاتيح متعددة بطريقة مدمجة (لا يمكنك القيام بذلك باستخدام النموذج "فاصلة موافق" الخاص). المزيد عن هذا: التحقق من وجود المفتاح في خرائط متعددة في حالة واحدة

10
icza

طريقة أفضل هنا

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

يذكر تحت "تعبيرات الفهرس" .

تعبير فهرس على خريطة a of type map [K] V يستخدم في مهمة أو تهيئة للنموذج الخاص

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

تعطي قيمة منطقية إضافية غير نمطية. تكون قيمة "موافق" صحيحة إذا كان المفتاح x موجودًا في الخريطة ، وكان غير صحيح.

4
mroman
    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 موجود؟ صحيح غير موجود؟ خاطئة

3
Lady_Exotel

يمكن استخدام تعيين قيمة اثنين لهذا الغرض. يرجى مراجعة برنامج عينة بلدي أدناه

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")
    }
}
1
Fathah Rehman P