【问题标题】:How to fill first sequence with elements of second sequence如何用第二个序列的元素填充第一个序列
【发布时间】:2018-02-28 20:07:42
【问题描述】:

我有两个序列,第一个序列更大或与第二个序列大小相同。

例如val first = 1 to 7val second = Seq(3, 5)。我想生成一个如下所示的序列:

first |second| result
    1 |      |   3  
    2 |      |   3
    3 |   3  |   3
    4 |      |   3
    5 |   5  |   5
    6 |      |   5
    7 |      |   5   

第二个例子:

val first = 1 to 7
val second = Seq(3, 5, 6)

result will be Seq(3, 3, 3, 3, 5, 6, 6)

我正在寻找一个通用的解决方案。

【问题讨论】:

  • 第二个 Seq 可以更长吗?可以 min(second) max(first) 还是秒中的值总是更少,并且总是在 Range 的范围内?它总是一个范围,还是可能是 (1,2,3, 6, 7, 8) 而 snd 是 (3,5),而 5 找不到匹配的伙伴?是否有易于理解的现实世界场景?

标签: scala scala-collections


【解决方案1】:

非常简单的单线解决方案。创建第二个列表的第一个元素的序列以及第二个列表中小于第一个列表的当前映射元素的所有元素,并取该序列中最大的元素。

val first = 1 to 7
val second = List(3, 5, 6)

val result = (first.map(x => (second.head +: second.filter(_ <= x)).last))

【讨论】:

  • 就简洁性和可读性而言,这是一个不错的解决方案,但如果输入数据很大,OP 应该小心,因为与其他解决方案相比,此解决方案效率较低。
【解决方案2】:

简单的方法:

scala> val first = 1 to 7 toList
first: List[Int] = List(1, 2, 3, 4, 5, 6, 7)

scala> val second = List(3,5)
second: List[Int] = List(3, 5)

scala> val result = first.map(x => if(x < second.tail.head) second.head else second.tail.head)
result: List[Int] = List(3, 3, 3, 3, 5, 5, 5)

但是,这不是很灵活,但可以满足您的问题。

【讨论】:

  • 谢谢。但我真的在寻找一般情况,如果第二个是List(3,5,6),你的代码将不起作用
【解决方案3】:

我自己找到了解决方案。给定问题中的序列

first.foldLeft((second, Seq.empty[Int])) { case ((sec, acc), f) =>
    if (sec.tail.isEmpty) (sec, sec.head +: acc)
    else if (f >= sec.tail.head) (sec.tail, sec.tail.head +: acc)
    else (sec, sec.head +: acc)
}._2.reverse

提供正确的结果

【讨论】:

    【解决方案4】:

    使用span的递归解决方案

    @annotation.tailrec
    def recurse(first: Seq[Int], second: Seq[Int], acc: Seq[Int] = List.empty): Seq[Int] = {
      second match {
        case a :: b :: tail =>
          val (f1, f2) = first.span(_ != b)
          recurse(f2, b :: tail, List.fill(f1.length)(a) ++ acc)
        case a :: Nil =>
          (List.fill(first.length)(a) ++ acc).reverse
      }
    }
    
    val first = 1 to 7
    
    println(recurse(first, Seq(3, 5)))
    // List(3, 3, 3, 3, 5, 5, 5)
    
    println(recurse(first, Seq(3, 5, 6)))
    // List(3, 3, 3, 3, 5, 6, 6)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      • 2021-05-05
      • 2022-08-18
      • 2020-12-24
      • 1970-01-01
      相关资源
      最近更新 更多