Kotlin 已弃用的 String.capitalize() 函数是否有更短的替代品?

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

Kotlin 弃用了

capitalize
类上的
String
函数,并且他们建议的替换非常长。这是一个例子,他们在弃用它时做出了正确的决定,但在用户体验上做出了错误的决定。

例如这段代码:

val x = listOf("foo", "bar", "baz").map { it.capitalize() }

被IDE“清理”成为:

val x = listOf("foo", "bar", "baz").map { it.replaceFirstChar {
                    if (it.isLowerCase()) it.titlecase(
                        Locale.getDefault()
                    ) else it.toString()
                } }

这太丑了。对此我们能做什么?

string kotlin deprecated capitalization
9个回答
80
投票

建议的替换很丑陋,因为它需要与

capitalize()
过去所做的相同:

  1. 取决于默认区域设置
  2. 不将大写的第一个字符转换为标题大小写(例如
    capitalize
    不会将前导 'DŽ' 转换为 'Dž' - 这里都是单个字符,尝试选择它们)

如果您不太关心此行为,您可以使用更简单的表达式,使用不变的语言环境,并无条件地对第一个字符进行标题大小写,即使是大写:

val x = listOf("foo", "bar", "baz").map { it.replaceFirstChar(Char::titlecase) }

这意味着,如果第一个字符是大写,如

'DŽ'
,它无论如何都会被转换为标题变体
'Dž'
,而原始代码不会触及它。这实际上可能是可取的。

capitalize()
已被弃用的原因之一是该方法的行为尚不清楚。例如:

  • 行为 #2 很奇怪
  • 句子中的单词不大写可能会出乎意料(C# 会对每个空格分隔的单词进行标题大写)
  • 不小写单词的其他字符也可能会出乎意料

如果您想故意保留当前的行为,但使其更方便使用,您可以随时使用适合您的名称来推出自己的扩展函数(“capitalize(d)”可能无法为不知情的人提供足够的信息读者):

fun String.titlecaseFirstCharIfItIsLowercase() = replaceFirstChar { 
    if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() 
}

或者对于具有不变区域设置且标题大写字符的版本:

fun String.titlecaseFirstChar() = replaceFirstChar(Char::titlecase)

37
投票

一个巧妙的解决方案是在 String 上定义一个新的扩展函数,它用一个更简洁的名称隐藏了血淋淋的细节:

/**
 * Replacement for Kotlin's deprecated `capitalize()` function.
 */
fun String.capitalized(): String {
    return this.replaceFirstChar { 
        if (it.isLowerCase())
            it.titlecase(Locale.getDefault())
        else it.toString() 
    }
}

现在您的旧代码可能如下所示:

val x = listOf("foo", "bar", "baz").map { it.capitalized() }

您需要在某个可以轻松导入的包的顶层定义扩展函数。例如,如果您有一个名为

my.package.KotlinUtils
(
KotlinUtils.kt
) 的 kotlin 文件,并且您将定义放入其中,如下所示:

package my.package

fun String.capitalized(): String {...}

然后您可以将其导入到其他包中:

import my.package.capitalized

7
投票
val fruits = listOf("baNana", "avocAdo", "apPle", "kiwifRuit")
fruits
    .filter { it.startsWith("a") }
    .sortedBy { it }
    .map { it.lowercase().replaceFirstChar(Char::uppercase) }
    .forEach { println(it) }

输出:

Apple
Avocado

6
投票

您可以对原始字符串调用replaceFirstChar函数并将转换函数作为输入传递。转换函数获取第一个字符并使用 uppercase() 函数将其转换为大写字符。

val list = listOf("foo", "bar", "baz") .map {
     it.replaceFirstChar { firstChar ->
          firstChar.uppercase()
     }
 }
println("List - > $list")

输出

List - > [Foo, Bar, Baz]

1
投票

这个怎么样?

fun main() {
    val x = listOf("foo", "bar", "baz").map { it[0].uppercase() + it.drop(1) }
    println(x)
}

输出:

[Foo, Bar, Baz]

1
投票

我发现了一种尝试将来自 API 的字符串大写的方法,它显然有效,在 Kotlin 文档中找到了它:

println("kotlin".replaceFirstChar { it.uppercase() }) // Kotlin

并在我的代码中像这样使用它:

 binding.textDescriptions.text = "${it.Year} - ${it.Type.replaceFirstChar {it.uppercase()}}"

0
投票

如果您不确定(也许您从 API 接收字符串)第一个字母是大写还是小写,您可以使用以下方法;

var title = "myTitle"
title.replaceFirstChar {
        if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else 
        it.toString()
    }

新标题将是“MyTitle”


0
投票

您可以使用此扩展函数将字符串的第一个字符大写

fun String.capitalize(): String {
        return this.replaceFirstChar {
            if (it.isLowerCase()) it.titlecase(Locale.getDefault())
            else it.toString()
        }
}

并像这样调用这个方法

"abcd".capitalize()

-2
投票
 val text = "FRIDAY"
 val result = text.lowercase().replaceFirstChar { it.uppercase() }
 println(result) //output: Friday

[注意:如果在转换之前没有添加 lowercase(),当你的第一个字母已经是大写时,它将无法正常工作。]

© www.soinside.com 2019 - 2024. All rights reserved.