文本中不包含数字时本地化复数

问题描述 投票:0回答:1

当文本中不包含数字时,本地化和复数字符串的正确方法是什么?

我知道我可以使用

AttributedString
执行以下操作(已经是一个很棒的功能):

var count = 3
AttributedString(localized: "^[\(count) Chief-of-staff](inflect: true)")
// "3 Chiefs-of-staff"

我想在表格/列表中列出姓名,并使用“Chief-of-staff”或“Chiefs-of-staff”作为列表标题,并根据列表中的姓名数量进行本地化。

继优秀文章here之后,这个用例看起来与

InflectionConcept
的现有实现类似。也许它需要一个新的
count
变形概念来实施。然后人们也许能够做这样的事情(伪代码,不起作用!):

var options = AttributedString.LocalizationOptions()
options.concepts = [.count(count)]

AttributedString(localized: "^[Chief-of-staff](agreeWithConcept: 1)", options: options)

我取得的唯一进展是直接使用

Morphology
,但这失败了,因为确定
GrammaticalNumber
的逻辑是特定于语言环境的。以下内容适用于英语和其他只有两种形式(单数和复数)的语言,但不适用于使用
pluralTwo
pluralFew
pluralMary
等的语言。

extension Morphology.GrammaticalNumber {
    init(count: Int) {
        switch count {
        case 1:     self = .singular
        default:    self = .plural
        }
    }
}

extension LocalizedStringResource.StringInterpolation {
    mutating func appendInterpolation(_ input: String, count: Int) {
        var morphology = Morphology()
        morphology.number = .init(count: count)
        
        var string = AttributedString(input)
        string.inflect = InflectionRule(morphology: morphology)
        
        appendInterpolation(string.inflected())
    }
}

AttributedString(localized: "\("Chief-of-staff", count: count)")

一种可能性是使用字符串中的数字,然后将其删除,但这感觉像是一个可怕的黑客:

var header = AttributedString(localized: "^[\(count) Chief-of-staff](inflect: true)")
let range = header.range(of: "\(count) ")!
header.removeSubrange(range)
// Chief-of-staff

我是否遗漏了一些明显的东西,或者有更简洁的解决方案吗?

swift foundation nslocalizedstring
1个回答
0
投票

虽然我同意这是一个黑客,但这里至少有一些包装可以使用您的解决方案隐藏混乱:

extension String {
    func pluralize() -> String {
        let count = 2
        var attributed = AttributedString(localized: "^[\(count) \(self)](inflect: true)")
        let range = attributed.range(of: "\(count) ")!
        attributed.removeSubrange(range)
        return String(attributed.characters)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.