我有一个字符串列表,我正在尝试保留唯一的字符串,并忽略字母大小写和空格
例如:import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
class MyTests {
@Test
fun `division by zero -- should throw ArithmeticException`() {
assertThrows<ArithmeticException> { 1 / 0 }
}
}
=> listOf("a", "A", "A ", "B")
所以我尝试了此解决方案:
listOf("a", "B")
输出:list = [a,A,B]
但是当我更改val list = listOf("a", "A", "A ", "B")
.distinctBy { it.toLowerCase() }
.distinctBy { it.trim() }
println("list = ${list}")
的顺序时,它出奇地起作用:
distinctBy
输出:list = [a,B]
我希望输出为第二个,但是为什么第一个代码不起作用?
当我更改项目的顺序时,我遇到了同样的问题:
val list = listOf("a", "A", "A ", "B")
.distinctBy { it.trim() }
.distinctBy { it.toLowerCase() }
println("list = ${list}")
输出:list = [a,A,B]
答案 0 :(得分:3)
distinctBy
不会更改列表的内容,而是使用给定的转换函数比较列表中的每个条目,然后返回一个新列表。
因此,即使a
和A
在您的第一个定义中是不同的,它们也只会返回找到的第一个匹配项(在本例中为a
)。
您的第一个非重复字符后的列表包含以下项:
[a, A , B]
下一个distinct接受这些元素,并通过修剪内容进行比较,这基本上会导致相同的结果,因为所有内容都是基于第二个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匹配项。
答案 1 :(得分:1)
val list = listOf("a", "A ", "A", "A ", "B")
.map { it -> it.trim() }
.distinctBy { it.toLowerCase() }
因为第一次修整,然后询问不同的值
如果您首先获得不同的值,则结果为list = [a, A , B]
所以修剪后给出:list = [a, A, B]
distinctBy
意味着获得所有不同的(不同的)物品
答案 2 :(得分:1)
在第一种情况下,当您应用.distinctBy { it.toLowerCase() }
时,它将比较["a", "a", "a ", "b" ]
的值,结果数组将为["a", "A ", "B"]
调用.distinctBy { it.trim() }
时,它将比较"a", "A", "B"
个字符串,得到["a", "A ", "B"]
在第二种情况下,应用.distinctBy { it.trim() }
后,您得到["a", "A", "B"]
,然后.distinctBy { it.toLowerCase() }
将比较["a","a","b"]
,并得到理想的结果
您还可以将两个操作合并在一个 distinctBy 块中:
val list = listOf("a", "A", "A ", "B")
.distinctBy { it.toLowerCase().trim() }