List 如何在Scala中复制两个数字

List 如何在Scala中复制两个数字,list,scala,duplicates,List,Scala,Duplicates,我想在Scala中复制两个数字,如下所示: duplicateDigits(List(1,2,3,4,5,6,7,8,9,10,11,345)) //> res0: List[Long] = List(11, 22, 33, 44, 55, 66, 77, 88, 99, 1010, 1111, 345345) 我还必须考虑以下模板: def duplicateDigits(xs: List[Int]): List[Long]= xs match { case Nil => Ni

我想在Scala中复制两个数字,如下所示:

duplicateDigits(List(1,2,3,4,5,6,7,8,9,10,11,345))

//> res0: List[Long] = List(11, 22, 33, 44, 55, 66, 77, 88, 99, 1010, 1111, 345345)

我还必须考虑以下模板:

def duplicateDigits(xs: List[Int]): List[Long]= xs match {
case Nil => Nil
case x::ys =>???
}
如果我有一个字符串列表,那就很容易了,因为我只需要将x乘以2,数字就会被复制,但是因为我处理的是整数值,所以我不知道怎么做

我得到的最接近的答案是:

case x :: ys =>  (x :: x) :: duplicateDigits(ys)
但我有一个错误:

value::不是Int的成员


有人知道怎么做吗?

您可以使用zip本身创建一个元组列表,然后将其展平,如下所示:

 xs.zip(xs).flatMap(pair => List(pair._1,pair._2))
或者干脆

def duplicate[A](xs:List[A]):List[A] = 
  xs match {
    case Nil => Nil
    case h :: t => h :: h :: duplicate(t)
  }

我的错,误读了这个问题。我不认为任何东西能打败
map(u.toString*2 toLong)
在这种情况下

使用数字是教授编程的基本任务之一。将数字转换成字符串是可行的,但通常情况下,这并不是学生所期望的。此外,将数字转换为字符串并返回也会带来糟糕的性能

这里有两种选择

使用递归辅助函数,将“填充”计算为
Long

def duplicateDigits(xs: List[Int]): List[Long] = {
  def padding(x: Int): Long = if (x == 0) 1 else padding(x / 10) * 10

  xs match {
    case Nil => Nil
    case x :: ys =>
      (padding(x) * x + x) :: duplicateDigits(ys)
  }
}
或者,使用
scanleet
内联计算“填充”。但看起来有点复杂:

def duplicateDigits(xs: List[Int]): List[Long] = xs match {
  case Nil => Nil
  case x :: ys =>
    (Stream.from(0)
      .scanLeft((1L, x.toLong)) { case ((i, cX), _) => (i * 10, cX / 10) }
      .dropWhile(_._2 > 0).head._1 * x + x) ::
      duplicateDigits(ys)
}

我知道OP要求提供模式匹配解决方案,但如果有其他选择,可以使用
折叠

def duplicateDigits(xs: List[Int]): List[Long] =
    xs.foldRight(List.empty[Long])((num, acc) => (num.toString * 2).toLong :: acc)

val l : List[Int] = List(1,2,3)
val res : List[Long] = duplicateDigits(l)

res shouldBe List(11L,22L,33L)

正如注释中所建议的,您可以在Scala中“乘”一个
字符串,因此:

def duplicateDigits(xs: List[Int]): List[Long]=
  xs.map(x => (x.toString * 2).toLong)

toLong
通常是不安全的(如果字符串不是有效的长数字,它就会抛出),但是在这个简单的例子中,我们可以忽略这个事实,因为我们是从
Int

导出
字符串的,为什么不
(u.toString*2)。toInt
?没有想到这一点。谢谢,效果非常好。事实上,你的解决方案将返回
List(1,1,2,2,3,3)
,而不是
List(11,22,33)
@mdm,哦,我真丢脸!我完全看错了描述。已更新。实际上,您的解决方案将返回列表(1,1,2,2,3,3),而不是列表(11,22,33)。另外,如果没有toLong的强制转换,代码将无法编译(在您的第一个示例中)。相应地改变了答案。与一张简单(且更容易阅读)的地图相比,这有什么优势?事实上,没有。我根本没想过。毫无疑问,地图是最好的解决方案。