¿Hay algo similar a the slice notation in Python en Scala?Notación de división en Scala?
Creo que esta es una operación realmente útil que debe incorporarse en todos los idiomas.
¿Hay algo similar a the slice notation in Python en Scala?Notación de división en Scala?
Creo que esta es una operación realmente útil que debe incorporarse en todos los idiomas.
scala> import collection.IterableLike
import collection.IterableLike
scala> implicit def pythonicSlice[A, Repr](coll: IterableLike[A, Repr]) = new {
| def apply(subrange: (Int, Int)): Repr = coll.slice(subrange._1, subrange._2)
| }
pythonicSlice: [A,Repr](coll: scala.collection.IterableLike[A,Repr])java.lang.Object{def apply(subrange: (Int, Int)): Repr}
scala> val list = List(3, 4, 11, 78, 3, 9)
list: List[Int] = List(3, 4, 11, 78, 3, 9)
scala> list(2 -> 5)
res4: List[Int] = List(11, 78, 3)
¿Esto esto?
Descargo de responsabilidad: No generalizada correctamente.
EDIT:
scala> case class PRange(start: Int, end: Int, step: Int = 1)
defined class PRange
scala> implicit def intWithTildyArrow(i: Int) = new {
| def ~>(j: Int) = PRange(i, j)
| }
intWithTildyArrow: (i: Int)java.lang.Object{def ~>(j: Int): PRange}
scala> implicit def prangeWithTildyArrow(p: PRange) = new {
| def ~>(step: Int) = p.copy(step = step)
| }
prangeWithTildyArrow: (p: PRange)java.lang.Object{def ~>(step: Int): PRange}
scala> implicit def pSlice[A](coll: List[A]) = new {
| def apply(prange: PRange) = {
| import prange._
| coll.slice(start, end).grouped(step).toList.map(_.head)
| }
| }
pSlice: [A](coll: List[A])java.lang.Object{def apply(prange: PRange): List[A]}
scala> val xs = List.range(1, 10)
xs: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> xs(3 ~> 9)
res32: List[Int] = List(4, 5, 6, 7, 8, 9)
scala> xs(3 ~> 9 ~> 2)
res33: List[Int] = List(4, 6, 8)
Véase el ScalaAPI here
Así que nola misma conveniencia de notación, pero la operación es no
rebanada def (a partir de: Int, hasta que: Int) : SEQ [A]
Selecciona un intervalo de elementos.
Selecciona un intervalo de elementos.
Nota: c.slice (de, a) es equivalente a (pero posiblemente más eficiente que) c.drop (de) .take (a - a)
del índice del primer devuelto elemento en esta secuencia. hasta el índice uno más allá del último elemento devuelto en esta secuencia.
rendimientos
una secuencia que contiene los elementos a partir de índice a partir de y se extienden hasta (pero no incluyendo) índice hasta de esta secuencia.
clases de definición de: IterableLike → TraversableLike
existe Método equivalente en Scala (con una sintaxis ligeramente diferente) para todos los tipos de secuencias:
scala> "Hello world" slice(0,4)
res0: String = Hell
scala> (1 to 10) slice(3,5)
res1: scala.collection.immutable.Range = Range(4, 5)
La diferencia más grande en comparación con rebanar en Python es que los índices de inicio y final son obligatorios en Scala.
Tenga en cuenta que esto hace el trabajo no es mediante el uso de apply
, pero generaliza a listas, cadenas, matrices, etc:
implicit def it2sl[Repr <% scala.collection.IterableLike[_, Repr]](cc: Repr) = new {
def ~>(i : Int, j : Int) : Repr = cc.slice(i,j)
}
El uso es:
scala> "Hello World" ~> (3, 5)
res1: java.lang.String = lo
scala> List(1, 2, 3, 4) ~> (0, 2)
res2: List[Int] = List(1, 2)
scala> Array('a', 'b', 'c', 'd') ~> (1, 3)
res3: Array[Char] = Array(b, c)
Es posible que desee cambiar el nombre del método a otra cosa que le apetezca.Exceptoapply
(porque ya hay una conversión String
-StringLike
que decora la secuencia con un método apply
- de manera similar con ArrayOps
- y ya es un método de aplicación en otros tipos de recolección tales como List
).
Gracias por Daniel por la sugerencia de utilizar una vista encuadernada.
Bueno, algunas personas prefieren un lenguaje que se mantenga pequeño, simple y limpio. No todo el azúcar sintáctico poco vale la pena. – soc
No estoy convencido de que Scala sea pequeño y simple. Comparado con algo como lua, de todos modos ... –
Comparando con Python Scala no se ve tan pequeño y simple, tiene muchos más constructos que Python. –