Tengo dos secuencias, la primera secuencia más grande o tiene el mismo tamaño que la segunda.

Por ejemplo para val first = 1 to 7 y val second = Seq(3, 5). Quiero generar una secuencia que se vea así:

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

Segundo ejemplo:

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

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

Estoy buscando una solución general.

1
addmeaning 28 feb. 2018 a las 14:04

4 respuestas

La mejor respuesta

Bastante sencillo, solución oneliner. Cree la secuencia del primer elemento de la segunda lista y todos los elementos de la segunda lista más pequeños que el elemento actualmente mapeado de la primera lista y tome el elemento más grande de esta secuencia.

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

val result = (first.map(x => (second.head +: second.filter(_ <= x)).last))
2
wrobel7 28 feb. 2018 a las 12:07

La manera fácil:

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)

Sin embargo, esto no es muy flexible pero satisface su pregunta.

1
airudah 28 feb. 2018 a las 11:12

Solución recursiva usando 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)
1
Tom 28 feb. 2018 a las 11:53

Encontré la solución yo mismo. Secuencias dadas en una pregunta

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

Proporciona el resultado correcto

1
addmeaning 28 feb. 2018 a las 11:50