当遍历代码中返回的映射时,由主题函数返回,键没有按顺序出现。
如何让键按顺序排列/对地图进行排序,以便键按顺序排列并且值对应?
package main import( "bufio" "fmt" "os" "regexp" "strings" ) func stringInArray(a string, list [214]string) bool{ for _, b := range list{ if b == a{ return true; } } return false } func inMap(a string, l map[string]string) bool{ for k, _ := range l{ if k == a{ return true } } return false } func tag(text string) map[int]map[string]string{ lexicon := make(map[string]string) f, err := os.Open("lexicon.txt") if err != nil{ fmt.Println(err) } r := bufio.NewReader(f) line, err := r.ReadString('\n') if err == nil{ lineAsArray := strings.Split(line, " ") tagsSplice := lineAsArray[1:(len(lineAsArray) - 1)] tagsString := strings.Join(tagsSplice, " ") lexicon[lineAsArray[0]] = tagsString } reg, err := regexp.Compile("[^a-zA-Z0-9\\s]") if err != nil{ fmt.Println(err) } text = strings.Replace(text, "-", " ", -1) text = reg.ReplaceAllString(text, "") matches := strings.Fields(strings.ToLower(text)) var x [2]string x[0] = "NN" x[1] = "NN" toReturn := make(map[int]map[string]string) for i, token := range matches{ //default to common noun m, ok := toReturn[i] if !ok{ m = make(map[string]string) toReturn[i] = m } toReturn[i]["token"] = token toReturn[i]["tag"] = "NN" if i > 0{ if toReturn[i]["tag"] == "NN" && (toReturn[i-1]["token"] == "would"){ toReturn[i]["tag"] = "VB"; } if (toReturn[i-1]["token"] == "the") && (toReturn[i]["token"] == "VB" || toReturn[i]["token"] == "VBD" || toReturn[i]["token"] == "VBP"){ toReturn[i]["tag"] = "NN" } } //if already in lexicon if inMap(token, lexicon){ toReturn[i]["tag"] = string(lexicon[token]) break } //convert to past-participle verb if ends with `ed` if strings.HasPrefix(toReturn[i]["tag"], "N") && strings.HasSuffix(token, "ed"){ toReturn[i]["tag"] = "VBN" } //convert to adverb if ends with `ly` if strings.HasPrefix(toReturn[i]["tag"], "N") && strings.HasSuffix(token, "ly"){ toReturn[i]["tag"] = "RB" } //convert to adjective if ends with `al` if strings.HasPrefix(toReturn[i]["tag"], "N") && strings.HasSuffix(token, "al"){ toReturn[i]["tag"] = "JJ" } //convert to plural noun if ends with `s` if toReturn[i]["tag"] == "NN" && strings.HasSuffix(toReturn[i]["token"], "s"){ toReturn[i]["tag"] = "NNS" } //convert to gerund if ends with `ing` if strings.HasPrefix(toReturn[i]["tag"], "N") && strings.HasSuffix(toReturn[i]["token"], "ing"){ toReturn[i]["tag"] = "VBG" } } stopWords := [214]string{ "a", "about", "above", "after", "again", "against", "all", "am", "among", "an", "and", "any", "are", "aren't", "arent", "as", "at", "be", "because", "been", "before", "being", "below", "between", "both", "but", "by", "can't", "cant", "cannot", "could", "couldn't", "couldnt", "did", "didn't", "didnt", "do", "does", "doesn't", "doesnt", "doing", "don't", "dont", "down", "during", "each", "few", "for", "from", "further", "had", "hadn't", "hadnt", "has", "hasn't", "have", "haven't", "havent", "having", "he", "he'd", "hed", "he'll", "he's", "hes", "her", "here", "here's", "heres", "hers", "herself", "him", "himself", "his", "how", "how's", "hows", "i", "i'd", "id", "i'll", "i'm", "im", "i've", "ive", "if", "in", "into", "is", "isn't", "isnt", "it", "it's", "its", "itself", "let's", "lets", "me", "more", "most", "mustn't", "mustnt", "my", "myself", "no", "nor", "not", "of", "off", "on", "once", "only", "or", "other", "ought", "our", "ours", "ourselves", "out", "over", "own", "same", "shan't", "shant", "she", "she'd", "shed", "she'll", "she's", "shes", "should", "shouldn't", "shouldnt", "so", "some", "such", "than", "that", "that's", "the", "their", "theirs", "them", "themselves", "then", "there", "there's", "theres", "these", "they", "they'd", "theyd", "they'll", "theyll", "they're", "theyre", "they've", "theyve", "this", "those", "through", "to", "too", "under", "until", "up", "very", "was", "wasn't", "wasnt", "we", "we'd", "we'll", "we're", "we've", "weve", "were", "weren't", "werent", "what", "what's", "when", "when's", "whens", "where", "where's", "wheres", "which", "while", "who", "who's", "whom", "why", "why's", "with", "won't", "wont", "would", "wouldn't", "wouldnt", "yet", "you", "you'd", "youd", "you'll", "youll", "you're", "youre", "you've", "youve", "your", "yours", "yourself", "yourselves", } isStopWord := map[string]bool{} for _, sw := range stopWords{ isStopWord[sw] = true; } for key, mapOne := range toReturn{ //delete stop words from toReturn if isStopWord[mapOne["token"]]{ delete(toReturn, key); } } return toReturn } func main(){ topic := tag("did. the quick, brown yet cardinal fox conveniently jump over the lazy-dog") for k, v := range topic{ fmt.Println("key:", k, "v:", v) } }
使用范围循环遍历map时,未指定迭代顺序,并且不能保证从一次迭代到下一次迭代顺序相同。由于 Go 1 运行时随机化地图迭代顺序,因为程序员依赖于先前实现的稳定迭代顺序。如果您需要稳定的迭代顺序,则必须维护一个单独的数据结构来指定该顺序。
这是我修改后的示例代码版本:http : //play.golang.org/p/dvqcGPYy3-
package main import ( "fmt" "sort" ) func main() { // To create a map as input m := make(map[int]string) m[1] = "a" m[2] = "c" m[0] = "b" // To store the keys in slice in sorted order keys := make([]int, len(m)) i := 0 for k := range m { keys[i] = k i++ } sort.Ints(keys) // To perform the opertion you want for _, k := range keys { fmt.Println("Key:", k, "Value:", m[k]) } }
输出:
Key: 0 Value: b Key: 1 Value: a Key: 2 Value: c