获取自然语言的语言列表如何?

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

How can I get list Languages from NaturalLanguage

问题

func LanguagesList () {
    let allLanguages = Locale.isoLanguageCodes
    let locale = Locale(identifier: "en_US")
    for languageCode in allLanguages {
        if let languageName = locale.localizedString(forIdentifier: languageCode) {
            print("\(languageCode): \(languageName)")
        }
    }
    let recognizer = NLLanguageRecognizer()
    let textRecognitionLanguages = recognizer.supportedRecognitionLanguages
    print(textRecognitionLanguages)
}
英文:

I want to get a list of available languages for text translations. The text is unknown.

I created a simple project:

import SwiftUI
import Foundation
import NaturalLanguage

struct ContentView: View {
    
    func LanguagesList () {
        let allLanguages = Locale.isoLanguageCodes
        let locale = Locale(identifier: "en_US")
        for languageCode in allLanguages {
            if let languageName = locale.localizedString(forIdentifier: languageCode) {
                print("\(languageCode): \(languageName)")
            }
        }
        let recognizer = NLLanguageRecognizer()
        recognizer.
        let textRecognitionLanguages = recognizer.availableRecognitionLanguages(for: .text)
        print(textRecognitionLanguages)
    }
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
            Button("Languages list") {
                LanguagesList()
            }
        }
        .padding()
    }
}

I tried to ask ChatGPT. It claims that this is how it should work (SDK 14, NaturalLanguage version 2.0). I updated the OS.

I have Xcode 14.3 includes Swift 5.8 and SDKs for iOS 16.4, iPadOS 16.4, tvOS 16.4, watchOS 9.4, and macOS Ventura 13.3.

The compiler throws 2 errors:

1. Cannot infer contextual base in reference to member 'text'

2. Value of type 'NLLanguageRecognizer' has no member 'availableRecognitionLanguages'

Is there a way to get a list of available languages for text translations. The text is not known in advance?

答案1

得分: 1

(从我的评论): 正如@HangarRash所说,availableRecognitionLanguages不存在。要查看完整的NLLanguage列表,请参阅枚举的文档:NLLanguage。对于许多枚举,尤其是您创建的枚举,有一个用于循环遍历所有情况的有用协议,这正是您尝试在上面执行的操作。这个协议称为CaseIterable,它不是NLLanguage符合的协议,但正如这篇Hacking with Swift文章所说,我们可以自己添加这个协议。以下是添加此符合性的示例:

extension NLLanguage: CaseIterable {
    public static var allCases: [NLLanguage] {
    [.amharic, .arabic, .armenian, .bengali, .bulgarian, .burmese, .catalan, .cherokee, .croatian, .czech, .danish, .dutch, .english, .finnish, .french, .georgian, .german, .greek, .gujarati, .hebrew, .hindi, .hungarian, .icelandic, .indonesian, .italian, .japanese, .kannada, .kazakh, .khmer, .korean, .lao, .malay, .malayalam, .marathi, .mongolian, .norwegian, .oriya, .persian, .polish, .portuguese, .punjabi, .romanian, .russian, .simplifiedChinese, .sinhalese, .slovak, .spanish, .swedish, .tamil, .telugu, .thai, .tibetan, .traditionalChinese, .turkish, .ukrainian, .urdu, .vietnamese, .undetermined]
    }
    
}

然后我们可以像这样循环遍历每种情况:

print(NLLanguage.allCases)
//打印每一种情况

我们必须自己声明这个符合性,这也意味着如果苹果发布了新的NLLanguage,我们必须更新它。以下是两个示例,一个是使用您上面提供的代码,另一个是通过ForEach显示所有情况的列表。首先,对于您上面提供的代码:

import SwiftUI
import Foundation
import NaturalLanguage

struct ContentView: View {
    
    func LanguagesList() {
        for lang in NLLanguage.allCases {
            let locale = Locale(identifier: lang.rawValue)
            if let languageName = locale.localizedString(forIdentifier: lang.rawValue) {
                print("\(lang.rawValue): \(languageName)")
            }
        }
        print(NLLanguage.allCases.map({ lang in
            lang.rawValue
        }))
        //或者,如果您想打印实际的语言名称,请使用以下内容:
//        print(NLLanguage.allCases.map({ lang in
//            Locale.current.localizedString(forIdentifier: lang.rawValue) ?? lang.rawValue
//        }))
    }
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
            Button("Languages list") {
                LanguagesList()
            }
        }
        .padding()
    }
}

接下来是ForEach

struct LanguagesListView: View {
    var body: some View {
        VStack{
            ForEach(NLLanguage.allCases, id: \.self) { lang in
                Text(Locale.current.localizedString(forIdentifier: lang.rawValue) ?? lang.rawValue)
            }
        }
    }
}

请注意,在生产中使用id: \.self并不是一个好主意,因为如果两个值相同,这可能导致未定义的行为。上面,我使用Locale,因为它显示了语言的完整字符串,例如"英语",而不是语言标识符"en"。如果您想显示原始值,只需传递lang.rawValue

英文:

(From my comment): As @HangarRash said, availableRecognitionLanguages does not exist. For a full list of NLLanguages, see the docs for the enum: NLLanguage. For many enums, especially ones that you create, there is a useful protocol for looping over all of the cases, which is exactly what you are trying to do above. This protocol, called CaseIterable, is not one that NLLanguage conforms to, but as this Hacking with Swift article says, we can make it conform ourselves. Here is an example of adding this conformance:

extension NLLanguage: CaseIterable {
    public static var allCases: [NLLanguage] {
    [.amharic, .arabic, .armenian, .bengali, .bulgarian, .burmese, .catalan, .cherokee, .croatian, .czech, .danish, .dutch, .english, .finnish, .french, .georgian, .german, .greek, .gujarati, .hebrew, .hindi, .hungarian, .icelandic, .indonesian, .italian, .japanese, .kannada, .kazakh, .khmer, .korean, .lao, .malay, .malayalam, .marathi, .mongolian, .norwegian, .oriya, .persian, .polish, .portuguese, .punjabi, .romanian, .russian, .simplifiedChinese, .sinhalese, .slovak, .spanish, .swedish, .tamil, .telugu, .thai, .tibetan, .traditionalChinese, .turkish, .ukrainian, .urdu, .vietnamese, .undetermined]
    }
    
}

And then we can loop over each case like this:

print(NLLanguage.allCases)
//Prints each and every case

We have to declare this conformance ourselves, which also means we have to update it if Apple releases a new NLLanguage. Here are two examples, one with the code that you provided above, and one displaying a list (via ForEach) of all of the cases. First, for the code you provided above:

import SwiftUI
import Foundation
import NaturalLanguage

struct ContentView: View {
    
    func LanguagesList() {
        for lang in NLLanguage.allCases {
            let locale = Locale(identifier: lang.rawValue)
            if let languageName = locale.localizedString(forIdentifier: lang.rawValue) {
                print("\(lang.rawValue): \(languageName)")
                        }
        }
        print(NLLanguage.allCases.map({ lang in
            lang.rawValue
        }))
        //Or, if you want to print the actual language names, use the following:
//        print(NLLanguage.allCases.map({ lang in
//            Locale.current.localizedString(forIdentifier: lang.rawValue) ?? lang.rawValue
//        }))
    }
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
            Button("Languages list") {
                LanguagesList()
            }
        }
        .padding()
    }
}

And next, a ForEach:

struct LanguagesListView: View {
    var body: some View {
        VStack{
            ForEach(NLLanguage.allCases, id: \.self) { lang in
                Text(Locale.current.localizedString(forIdentifier: lang.rawValue) ?? lang.rawValue)
            }
        }
    }
}

Please note that it is not a good idea to use id: \.self in production, as if two values are the same, this can lead to undefined behavior. Above, I am using Locale because this displays the full String for the language - such as "English", rather than the language identifier "en". If you want to display the raw values, then just pass in lang.rawValue.

huangapple
  • 本文由 发表于 2023年4月7日 03:33:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75953149.html
匿名

发表评论

匿名网友

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

确定