Make Translation Func Map in Go Have "Repeat" Keys Without Being Too Repetitive or Inefficient

huangapple go评论77阅读模式
英文:

Make Translation Func Map in Go Have "Repeat" Keys Without Being Too Repetitive or Inefficient

问题

我想创建一个带有数据结构的go函数,让我输入一个字符串和一个目标语言,然后得到一个连接在一起的翻译结果。

这是我想要的:

translateKeyword("es-US", "mathe") // 输出为 "matemáticas"
translateKeyword("en-US", "matemáticas") // 输出为 "math"
translateKeyword("de-DE", "math") // 输出为 "mathe"

我已经在go中创建了一个函数,如果你给出一个英文单词和一个目标语言,你会得到一个翻译结果。

func translateKeyword(lang, keyword string) string {
  keywordDictionary := map[string]map[string]string{
    "home": {
      "en-US": "home",
      "es-US": "inicio",
      "de-DE": "start",
    },
    "about": {
      "en-US": "about",
      "es-US": "conóceme",
      "de-DE": "über",
    },
    // 更多...
  }

  translation, ok := keywordDictionary[keyword][lang]
  if ok {
    return translation
  }
  return keyword
}
translateKeyword("de-DE", "about") // 输出为 "über"
translateKeyword("es-US", "über") // 输出为 "über" :(

你还可以在下面放置一个嵌套循环,以找到你插入的任何关键字,然后正常遍历映射。你也可以重复键多次,使得西班牙语和德语分别成为键,但肯定有比这更好的方法。

不过,我真正想要的是找到一种简单的方法,使任何翻译都可以作为键。我想找到一种方法,不必在底部创建一个丑陋且低效的循环,也不必将所有的翻译分散开来,以便在需要轻松添加或删除新的翻译时使用。有什么方法可以让我的生活更轻松吗?

英文:

I wanna make a go func with a data structure that lets me feed in a string and a desired language and get a translation out where each translation is connected to the others somehow.

This is what I want:

translateKeyword("es-US", "mathe") // output is "matemáticas"
translateKeyword("en-US", "matemáticas") // output is "math"
translateKeyword("de-DE", "math") // output is "mathe"

I already made a func in go where if you give an English word and a desired language, you get a translated output.

func translateKeyword(lang, keyword string) string {
  keywordDictionary := map[string]map[string]string{
    "home": {
      "en-US": "home",
      "es-US": "inicio",
      "de-DE": "start",
    },
    "about": {
      "en-US": "about",
      "es-US": "conóceme",
      "de-DE": "über",
    },
    // more....
  }

  translation, ok := keywordDictionary[keyword][lang]
  if ok {
    return translation
  }
  return keyword
}
translateKeyword("de-DE", "about") // output is "über" 
translateKeyword("es-US", "über") // output is "über" :(

You can also put a nested loop underneath to find whatever keyword you inserted to find the English word then just go through the map normally. You can also just repeat the keys over and over again so that Spanish and German each become the keys, but there has to be a better way than that.

What I really want though is to find a simple way to make any translation work as the key. I wanna find a way to do without having to make an ugly, inefficient loop at the bottom or having to scatter all my translations away from each other in case I want to add or delete a new set easily. What can I do to make my life easier?

答案1

得分: 1

给定你已经有的输入,你可以构建你想要的字典,例如:

func build_dict(in map[string]map[string]string) (out map[string]map[string]string) {
	out = make(map[string]map[string]string)
	for _, m := range in {
		for l1, w1 := range m {
			if out[l1] == nil {
				out[l1] = make(map[string]string)
			}
			for _, w2 := range m {
				out[l1][w2] = w1
			}
		}
	}
	return out
}

然后你可以这样做:

var dictionary = build_dict(map[string]map[string]string{
	"home": {
		"en-US": "home",
		"es-US": "inicio",
		"de-DE": "start",
	},
	// ...
})

然后你的函数可以更新为:

func translateKeyword(lang, kw string) string {
	x, ok := dictionary[lang][kw]
	if ok {
		return x
	}
	return "<unknown>"
}

https://go.dev/play/p/9iIlAzLpwow

如你所见,build_dict 函数不需要 map 中的根键,所以你可以只用一个 map 切片来实现相同的功能,即:

[]map[string]string{{
	"en-US": "math",
	"es-US": "matemáticas",
	"de-DE": "mathe",
}, {
	"en-US": "about",
	"es-US": "conóceme",
	"de-DE": "über",
}}
英文:

Given the input you already have you can build the dictionary you want, e.g.:

func build_dict(in map[string]map[string]string) (out map[string]map[string]string) {
	out = make(map[string]map[string]string)
	for _, m := range in {
		for l1, w1 := range m {
			if out[l1] == nil {
				out[l1] = make(map[string]string)
			}
			for _, w2 := range m {
				out[l1][w2] = w1
			}
		}
	}
	return out
}

Then you can do

var dictionary = build_dict(map[string]map[string]string{
	&quot;home&quot;: {
		&quot;en-US&quot;: &quot;home&quot;,
		&quot;es-US&quot;: &quot;inicio&quot;,
		&quot;de-DE&quot;: &quot;start&quot;,
	},
	// ...
})

And your function can be updated to:

func translateKeyword(lang, kw string) string {
	x, ok := dictionary[lang][kw]
	if ok {
		return x
	}
	return &quot;&lt;unknown&gt;&quot;
}

https://go.dev/play/p/9iIlAzLpwow


As you can see the build_dict function doesn't need the root key in the map, so you could achieve the same thing with just a slice of maps, i.e.

[]map[string]string{{
	&quot;en-US&quot;: &quot;math&quot;,
	&quot;es-US&quot;: &quot;matem&#225;ticas&quot;,
	&quot;de-DE&quot;: &quot;mathe&quot;,
}, {
	&quot;en-US&quot;: &quot;about&quot;,
	&quot;es-US&quot;: &quot;con&#243;ceme&quot;,
	&quot;de-DE&quot;: &quot;&#252;ber&quot;,
}}

huangapple
  • 本文由 发表于 2023年7月21日 14:09:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76735501.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定