अपने मूल्यों द्वारा मानचित्र [स्ट्रिंग] इंट को कैसे सॉर्ट करें?


81

इस कोड ब्लॉक को देखते हुए

map[string]int {"hello":10, "foo":20, "bar":20}

मैं प्रिंट आउट लेना चाहूंगा

foo, 20
bar, 20
hello, 10

उच्चतम से निम्नतम के क्रम में

धन्यवाद!

जवाबों:


92

एंड्रयू गेरैंड द्वारा गोलंग-नट्स पर उत्तर मिला

आप len / less / swap फ़ंक्शन लिखकर सॉर्ट इंटरफ़ेस लागू कर सकते हैं

func rankByWordCount(wordFrequencies map[string]int) PairList{
  pl := make(PairList, len(wordFrequencies))
  i := 0
  for k, v := range wordFrequencies {
    pl[i] = Pair{k, v}
    i++
  }
  sort.Sort(sort.Reverse(pl))
  return pl
}

type Pair struct {
  Key string
  Value int
}

type PairList []Pair

func (p PairList) Len() int { return len(p) }
func (p PairList) Less(i, j int) bool { return p[i].Value < p[j].Value }
func (p PairList) Swap(i, j int){ p[i], p[j] = p[j], p[i] }

मूल पोस्ट के लिए, कृपया इसे यहां देखें https://groups.google.com/forum/# ​​.topic/golang-nuts/FT7cjmcL7gw


1
... सिवाय Lessगलत परिणाम के लौट रहा है। रिवर्स सॉर्ट के लिए, का उपयोग करें >
फ्रेड फू

3
@larsmans मेरा बुरा! इस पर ध्यान दिलाने के लिए धन्यवाद। मैंने इसके बजाय क्रमबद्ध का उपयोग किया है। उल्टा परिणाम प्राप्त करने के लिए
samol

2
इससे भी बेहतर, मैं इसके बारे में भी नहीं जानता था sort.Reverse। +1।
फ्रेड फू

72

1.8 में एक नया सॉर्ट है। लिस् फंक्शन 1.8 है, इसलिए अब यह सरल है।

package main

import (
    "fmt"
    "sort"
)

func main() {
    m := map[string]int{
        "something": 10,
        "yo":        20,
        "blah":      20,
    }

    type kv struct {
        Key   string
        Value int
    }

    var ss []kv
    for k, v := range m {
        ss = append(ss, kv{k, v})
    }

    sort.Slice(ss, func(i, j int) bool {
        return ss[i].Value > ss[j].Value
    })

    for _, kv := range ss {
        fmt.Printf("%s, %d\n", kv.Key, kv.Value)
    }
}

https://play.golang.org/p/y1_WBENH4N


मुझे यह पसंद नहीं है कि आउटपुट मेरे द्वारा शुरू किए गए नक्शे के साथ नहीं है
hendry

@ यह प्रश्न मूल प्रश्न में प्रारूप के जवाब में है। Go1.12 में आप केवल नक्शा प्रिंट कर सकते हैं और इसे हल किया जाएगा, इस मुद्दे को देखें: github.com/golang/go/issues/21095
voutasaurus

लगभग सही है, मैं सुझाव देता हूं कि समान मूल्य वाले तत्वों को संभालें।
टॉमासो बारबुगली

@TommasoBarbugli कैसे? उन्हें स्थिर करो? या वर्णानुक्रम में हल किया? बहुत यकीन है कि स्थिरता असंभव है क्योंकि गो विशेष रूप से आपको संकलक के लिए महत्वपूर्ण नहीं कहे जाने वाले आदेश पर भरोसा करने से रोकने के लिए विशेष रूप से मैप इटरेशन ऑर्डर को यादृच्छिक करता है। वर्णानुक्रम के लिए आप आसानी से क्रमबद्ध किए गए अनाम फ़ंक्शन को संशोधित कर सकते हैं ।lice
voutasaurus

1
इसमें सॉर्ट भी है। स्लाइसस्टेबल (गो 1.8 में भी जोड़ा गया है) जो समान तत्वों के मूल क्रम को सुरक्षित रखता है।
डेव यारवुड

16

उदाहरण के लिए:

package main

import (
        "fmt"
        "sort"
)

func main() {
        m := map[string]int{"hello": 10, "foo": 20, "bar": 20}
        n := map[int][]string{}
        var a []int
        for k, v := range m {
                n[v] = append(n[v], k)
        }
        for k := range n {
                a = append(a, k)
        }
        sort.Sort(sort.Reverse(sort.IntSlice(a)))
        for _, k := range a {
                for _, s := range n[k] {
                        fmt.Printf("%s, %d\n", s, k)
                }
        }
}

खेल का मैदान


आउटपुट:

foo, 20
bar, 20
hello, 10

@DarshanComputing: धन्यवाद, निश्चित।
zzzz

1
यह मानता है कि मूल्यों की पहचान नहीं है।
newacct

2
@newacct: यह केवल ओपी समस्या को हल करता है, सामान्य मामले को नहीं ;-)
zzzz

यह समाधान वह है जो मेरे मामले के साथ-साथ समझने के लिए सरल है।
टॉमी

1

मुझे अक्सर map[string]intकुछ गिनने की ज़रूरत होती है जो मैं गिन रहा हूँ और निम्नलिखित का उपयोग कर रहा हूँ।

func rankMapStringInt(values map[string]int) []string {
    type kv struct {
        Key   string
        Value int
    }
    var ss []kv
    for k, v := range values {
        ss = append(ss, kv{k, v})
    }
    sort.Slice(ss, func(i, j int) bool {
        return ss[i].Value > ss[j].Value
    })
    ranked := make([]string, len(values))
    for i, kv := range ss {
        ranked[i] = kv.Key
    }
    return ranked
}

मूल्य के क्रम में कुंजियों पर पुनरावृति करने के लिए इसका उपयोग करें

values := map[string]int{"foo": 10, "bar": 20, "baz": 1}

for i, index := range rankMapStringInt(values) {
    fmt.Printf("%3d: %s -> %d", i, index, values[index])
}

0

मेरे मामले में, मैं अपने द्वारा बनाए गए एक कार्यक्रम से निपट रहा था। इस कार्यक्रम में, मैंने आपके साथ, stringऔर की तरह एक मैप बनाया int। तब मुझे आपकी तरह पता चला कि गो डोंट के पास वास्तव में इस तरह से कुछ बनाने का एक अंतर्निहित तरीका है। मैं अन्य उत्तरों को पढ़ता हूं और वास्तव में जैसा मैं पढ़ता हूं वैसा नहीं होता।

इसलिए मैंने समस्या के बारे में अलग तरीके से सोचने की कोशिश की। गो छँटनी के साथ छाँटे का उपयोग कर सकते हैं । इसके अलावा, गो एक कस्टम तुलनित्र के साथ Sort.Slice का उपयोग कर सकते हैं । तो के मानचित्र बनाने की बजाय stringऔर int, मैं एक बनाया structके stringऔर int। फिर आप छाँट सकते हैं:

package main

import (
   "fmt"
   "sort"
)

type File struct {
   Name string
   Size int
}

func main() {
   a := []File{{"april.txt", 9}, {"may.txt", 7}}
   f := func (n, n1 int) bool {
      return a[n].Size < a[n1].Size
   }
   sort.Slice(a, f)
   fmt.Println(a)
}

यह सभी के लिए काम नहीं करेगा, क्योंकि हो सकता है कि आप किसी और द्वारा बनाए गए नक्शे से निपटने के लिए मजबूर होंगे। लेकिन यह मेरे लिए उपयोगी था। अच्छा हिस्सा है, अन्य सभी उत्तरों के विपरीत, यह कोई लूप का उपयोग नहीं करता है।


-1

मान द्वारा पहले कुंजियों को क्रमबद्ध करें और फिर इसे मैप करें:

package main

import (
    "fmt"
    "sort"
)

func main() {
    counts := map[string]int{"hello": 10, "foo": 20, "bar": 20}

    keys := make([]string, 0, len(counts))
    for key := range counts {
        keys = append(keys, key)
    }
    sort.Slice(keys, func(i, j int) bool { return counts[keys[i]] > counts[keys[j]] })

    for _, key := range keys {
        fmt.Printf("%s, %d\n", key, counts[key])
    }
}

1
मुझे यकीन है कि कौन निराश है, शायद वे जो तुलनित्र कार्य को ध्यान से नहीं पढ़ते हैं। इसके अलावा स्वीकृत उत्तर प्रिंटआउट ओपी के लिए कहा गया उत्पादन नहीं करता है, बल्कि नए डेटास्ट्रक्चर का परिचय देता है जिसे वास्तविक कोड में बनाए रखना पड़ता है। यहाँ मेरे जवाब के लिए खेल का मैदान लिंक है play.golang.org/p/Y4lrEm2-hT5
AlexanderYastrebov
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.