如何在不使用内置库(如 distinct、groupBy(identity)、toSet 等)的情况下从列表中删除重复项

How to remove duplicates from list without using in inbuilt libraries such as distinct, groupBy(identity), toSet.. Etc

我想编写一个 Scala 程序,将命令行参数作为列表输入并提供不重复的输出列表。 我想在不使用任何库的情况下了解它的自定义实现。

输入:4 3 7 2 8 4 2 7 3 输出:4 3 7 2 8

val x= List(4, 3, 7, 2, 8, 4, 2, 7, 3)
x.foldLeft(List[Int]())((l,v)=> if (l.contains(v)) l else  v :: l)

如果你不能使用包含你可以再做一次折叠

x.foldLeft(List[Int]())((l,v)=> if (l.foldLeft(false)((contains,c)=>if (c==v ) contains | true else contains | false)) l else  v :: l)

这是一种使用递归执行此操作的方法。我试图以一种最容易解释的方式进行布局:

import scala.annotation.tailrec

@tailrec
def getIndividuals(in: List[Int], out: List[Int] = List.empty): List[Int] = {
  if(in.isEmpty) out
  else if(!out.contains(in.head)) getIndividuals(in.tail, out :+ in.head)
  else getIndividuals(in.tail, out)
}

val list = List(1, 2, 3, 4, 5, 4, 3, 5, 6, 0, 7)
val list2 = List(1)
val list3 = List()
val list4 = List(3, 3, 3, 3)

getIndividuals(list) // List(1, 2, 3, 4, 5, 6, 0, 7)
getIndividuals(list2) // List(1)
getIndividuals(list3) // List()
getIndividuals(list4) // List(3)

此函数有两个参数,inout,并遍历 in 列表中的每个元素,直到它为空(通过使用 tail 调用自身in)。一旦 in 为空,函数输出 out 列表。

如果 out 列表不包含您当前正在查看的 in 的值,该函数将使用 in 的尾部和 in 添加到 out 列表的末尾。

如果out 确实包含你当前正在查看的in的值,它只是用in的尾巴调用自己和当前 out 列表。

注意: 这是 Arnon 提出的 fold 方法的替代方法。我个人会编写一个像我的函数,然后在必要时将其重构为 fold 函数。我不自然地以功能性的方式思考,fold-y 所以像这样布局有助于我想象在我试图计算出逻辑时发生了什么。