2012-11-16 5 views
47

अगर मैं एक नक्शा मीटर वहाँ मूल्यों का एक टुकड़ा होने का एक बेहतर तरीका है v तोगोलांग में मानचित्र से मूल्यों का एक टुकड़ा प्राप्त करने का एक अच्छा तरीका है?

package main 
import (
    "fmt" 
) 

func main() { 
    m := make(map[int]string) 

    m[1] = "a" 
    m[2] = "b" 
    m[3] = "c" 
    m[4] = "d" 

    // Can this be done better? 
    v := make([]string, len(m), len(m)) 
    idx := 0 
    for _, value := range m { 
     v[idx] = value 
     idx++ 
    } 

    fmt.Println(v) 
} 

वहाँ एक नक्शे के एक निर्मित सुविधा है? क्या गो पैकेज में कोई फ़ंक्शन है, या अगर मुझे करना है तो यह सबसे अच्छा कोड है?

+0

'_' अपने पाश के लिए, यह IDX फोन और IDX ++ व्यापार –

+0

नहीं, वह नहीं कर सकते हैं खाई, जब आप एक नक्शा, मूल्य नहीं सूचकांक यह कुंजी रिटर्न से अधिक रेंज, मूल्य में। अपने उदाहरण में वह पहली कुंजी के रूप में 1 का उपयोग करता है और यह स्लाइस वी में इंडेक्स को गलत बना देगा क्योंकि स्टार्ट इंडेक्स शून्य नहीं होगा, और जब यह 4 हो जाएगा तो यह सीमा से बाहर होगा। https://play.golang.org/p/X8_SbgxK4VX – Popmedic

उत्तर

29

दुर्भाग्य से, नहीं। ऐसा करने के लिए कोई अंतर्निहित तरीका नहीं है।

एक तरफ ध्यान दें के रूप में, आप अपने टुकड़ा निर्माण में क्षमता तर्क को छोड़ सकते हैं:

v := make([]string, len(m)) 

क्षमता लंबाई यहां के बराबर हो जाए निहित है।

28

jimt के पद पर एक अतिरिक्त के रूप में:

तुम भी append उपयोग कर सकते हैं के बजाय स्पष्ट रूप से उनके सूचकांक करने के लिए मान निर्दिष्ट:

m := make(map[int]string) 

m[1] = "a" 
m[2] = "b" 
m[3] = "c" 
m[4] = "d" 

v := make([]string, 0, len(m)) 

for _, value := range m { 
    v = append(v, value) 
} 

ध्यान दें कि लंबाई (अभी तक कोई तत्व मौजूद) शून्य है लेकिन क्षमता (आवंटित स्थान) m के तत्वों की संख्या के साथ शुरू किया गया है। यह किया जाता है इसलिए append स्लाइस v रन आउट की क्षमता हर बार स्मृति आवंटित करने की आवश्यकता नहीं है।

आप make क्षमता मूल्य के बिना टुकड़ा भी कर सकते हैं और append अपने लिए स्मृति आवंटित कर सकते हैं।

+0

मैं सोच रहा था कि यह धीमा होगा (सामने आवंटन मानते हुए)? मैंने एक नक्शा [int] int के साथ एक कच्चे बेंचमार्क किया और यह लगभग 1-2% धीमा लग रहा था। कोई विचार अगर यह चिंता करने के लिए कुछ है या बस इसके साथ जाना है? – masebase

+1

मैं थोड़ा धीमा होने का अनुमान लगाऊंगा लेकिन यह अंतर ज्यादातर मामलों में नगण्य है। [बेंचमार्क प्रत्यक्ष असाइनमेंट की तुलना और संलग्न] [http://pastie.org/5393131)। – nemo

0

जहां तक ​​मुझे वर्तमान में पता है, तो कम से कम/दो/प्रतियों के बिना परिणामस्वरूप स्ट्रिंग में स्ट्रिंग्स/बाइट्स के संयोजन के लिए एक तरीका तरीका नहीं है।

आपको वर्तमान में एक [] बाइट विकसित करना है क्योंकि सभी स्ट्रिंग मान हैं, फिर आपको भाषा को 'धन्य' स्ट्रिंग ऑब्जेक्ट बनाने के लिए स्ट्रिंग बिल्टिन का उपयोग करना होगा, जो कि कहीं कहीं से बफर को कॉपी करेगा [] बाइट का समर्थन करने वाले पते का संदर्भ हो सकता है।

यदि कोई [] बाइट उपयुक्त है तो आप बाइट्स पर बहुत ही मामूली सीसा प्राप्त कर सकते हैं। एक आवंटन करके और प्रतिलिपि बनाकर कार्य करें अपने आप को कॉल करें।

package main 
import (
    "fmt" 
) 

func main() { 
m := make(map[int]string) 

m[1] = "a" ; m[2] = "b" ;  m[3] = "c" ; m[4] = "d" 

ip := 0 

/* If the elements of m are not all of fixed length you must use a method like this; 
* in that case also consider: 
* bytes.Join() and/or 
* strings.Join() 
* They are likely preferable for maintainability over small performance change. 

for _, v := range m { 
    ip += len(v) 
} 
*/ 

ip = len(m) * 1 // length of elements in m 
r := make([]byte, ip, ip) 
ip = 0 
for _, v := range m { 
    ip += copy(r[ip:], v) 
} 

// r (return value) is currently a []byte, it mostly differs from 'string' 
// in that it can be grown and has a different default fmt method. 

fmt.Printf("%s\n", r) 
} 
बजाय
संबंधित मुद्दे

 संबंधित मुद्दे