我有一个字符串列表,我试图保留唯一不同的字符串,并忽略字母大小写和空格

例如:listOf("a", "A", "A ", "B") => listOf("a", "B")
所以我尝试了这个解决方案:

val list = listOf("a", "A", "A  ", "B")
        .distinctBy { it.toLowerCase() }
        .distinctBy { it.trim() }

println("list = ${list}")



但是当我更改distinctBy顺序时,它出奇地起作用:
val list = listOf("a", "A", "A  ", "B")
        .distinctBy { it.trim() }
        .distinctBy { it.toLowerCase() }

println("list = ${list}")



我希望输出为第二个,但是为什么第一个代码不起作用?

当我更改项目的顺序时,我遇到了同样的问题:
   val list = listOf("a", "A  ", "A", "B")
            .distinctBy { it.toLowerCase() }
            .distinctBy { it.trim() }

    println("list = ${list}")

最佳答案

distinctBy不会更改列表的内容,而是使用给定的转换函数比较列表中的每个条目,然后返回一个新列表。

因此,即使aA在您的第一个定义中是不同的,它也只返回找到的第一个匹配项(在本例中为a)。
您在第一个非重复字符之后的列表包含以下各项:

[a, A  , B]

下一个distinct接受这些元素,并通过修剪内容进行比较,这基本上会导致相同的结果,因为所有内容都是基于第二个distinct转换函数的。

您可能想做的是:
listOf("a", "A", "A  ", "B")
   .distinctBy { it.toLowerCase().trim() }

实际上结合了两种转换功能并导致:
[a, B]

另外,您可以执行以下操作:
listOf("a", "A", "A  ", "B")
    .map(String::toLowerCase)
    .map(String::trim)
    .distinct()
    .also(::println)

然后返回:
[a, b]

或者,如果您真的在乎收到的输入是:
listOf("a", "A", "A  ", "B")
    .groupBy { it.toLowerCase().trim() }
    .let(::println)

返回:
{a=[a, A, A  ], b=[B]}

从这里您可以获取一个或全部〜real输入,例如您可以添加.map { it.value[0] }再次返回任何组的第一个〜real匹配项。

07-24 09:36