2

假设我有一个功能:

def f(i: Int): String = i.toString

我如何定义xxx例如(假设我可以在没有隐式转换的情况下将方法添加到列表中):

val source1: List[List[Int]] = List(List(1,2), List(3,4))
val source2: List[Int] = List(1,2)

val result1: List[List[String]] = source1.xxx(f)
val result2: List[String] = source2.xxx(f)

因为与

列表 [ _ ]

我不知道 _ 是否可以应用地图。可能吗?

4

3 回答 3

1

你可以试试这个:

object Container1 {
  implicit class RichList1(l: List[List[Int]]) {
    def xxx(f: (Int) => String): List[List[String]] = {
      l.map(l => l.map(n => f(n)))
    }
  }
}

object Container2 {
  implicit class RichList2(l: List[Int]) {
    def xxx(f: (Int) => String): List[String] = {
      l.map(n => f(n))
    }
  }
}

object Mapping extends App {
  def f(i: Int): String = i.toString

  val source1: List[List[Int]] = List(List(1, 2), List(3, 4))
  val source2: List[Int] = List(1, 2)

  import Container1._
  val result1a: List[List[String]] = source1.xxx(f)
  println(result1a)

  import Container2._
  val result2a: List[String] = source2.xxx(f)
  println(result2a)

}
于 2013-06-06T16:58:04.013 回答
1

看起来您正在尝试将您的函数应用于集合的最里面的项目,而不管您的值嵌套有多深(在这种情况下,List[T]List[List[T]])。

trait CanMapInner[WrappedV, WrappedB, V, B] {
  def mapInner(in: WrappedV, f: V ⇒ B): WrappedB
}

// simple base case (no nesting involved).
implicit def simpleMapper[V, B] = new CanMapInner[V, B, V, B] {
  def mapInner(in: V, f: (V) ⇒ B): B = f(in)
}

// drill down one level of "List".
implicit def wrappedMapper[V, B, InnerV, InnerB](implicit innerMapper: CanMapInner[InnerV, InnerB, V, B]) =
  new CanMapInner[List[InnerV], List[InnerB], V, B] {
    def mapInner(in: List[InnerV], f: (V) ⇒ B): List[InnerB] =
      in.map(innerMapper.mapInner(_, f))
  }

implicit class XXX[WrappedV](list: List[WrappedV]) {
  def xxx[V, B, WrappedB](f: V ⇒ B)(implicit mapper: CanMapInner[WrappedV, WrappedB, V, B]) = {
    list.map(inner ⇒ mapper.mapInner(inner, f))
  }
}

改编自qmajor解决方案Map

用法:

def f(i: Int): String = "Hello " + i.toString

val source1: List[List[Int]] = List(List(1, 2), List(3, 4))
val source2: List[Int] = List(1, 2)

val result1: List[List[String]] = source1.xxx(f)
val result2: List[String] = source2.xxx(f)

Console println source1
// > List(List(1, 2), List(3, 4))
Console println source2
// > List(1, 2)
Console println result1
// > List(List(Hello 1, Hello 2), List(Hello 3, Hello 4))
Console println result2
// > List(Hello 1, Hello 2)

f我出于演示目的更改了您的功能。

于 2013-06-06T17:36:53.890 回答
0

你可以使用 shapeless 的Scrap Your Boilerplate来做到这一点。从自述文件复制的示例:

val nested = List(Option(List(Option(List(Option(23))))))

val succ = everywhere(inc)(nested)
succ == List(Option(List(Option(List(Option(24))))))

如果你准备好包含一个库来做到这一点,这取决于你。

于 2013-06-06T17:18:45.977 回答