Scala Learning(2): map, flatMap, filter与For表达式

简介:

本文叙述Collections里最常见的三种操作map, flatMap, filter,与For表达式的关系。

List对三种方法的实现

map在List的实现:

abstract class List[+T] {
  def map[U](f: T => U): List[U] = this match {
    case x :: xs => f(x) :: xs.map(f)
    case Nil => Nil
  }
}

flatMap在List的实现:

abstract class List[+T] {
  def flatMap[U](f: T => List[U]): List[U] = this match {
    case x :: xs => f(x) ++ xs.flatMap(f)
    case Nil => Nil
  }
}

filter在List的实现:

abstract class List[+T] {
  def filter(p: T => Boolean): List[T] = this match {
    case x :: xs =>
      if (p(x)) x :: xs.filter(p) else xs.filter(p)
    case Nil => Nil
  }
}

For表达式

下面这段逻辑,可以在for里简单表达:

(1 until n) flatMap (i =>
  (1 until i) filter (j => isPrime(i + j)) map
    (j => (i, j)))
for {
  i <- 1 until n
  j <- 1 until i
  if isPrime(i + j)
} yield (i, j)

for与map

for (x <- e1) yield e2

// translated to
e1.map(x => e2)

for与filter

for (x <- e1 if f; s) yield e2

// translated to
for (x <- e1.withFilter(x => f); s) yield e2

for与flatMap

for (x <- e1; y <- e2; s) yield e3

// translated to
e1.flatMap(x => for (y <- e2; s) yield e3)

for与Pattern Matching

结合前一篇文章(JSON表达)的例子,用for来做map、filter的操作:

val data: List[JSON] = ...
for {
  JObj(bindings) <- data
  JSeq(phones) = bindings("phoneNumbers")
  JObj(phone) <- phones
  JStr(digits) = phone("number")
  if digits startsWith "212"
} yield (bindings("firstName"), bindings("lastName"))

for里面Pattern Matching的大致翻译过程:

pat <- expr
// to
x <- expr withFilter {
    case pat => true
    case _ => false
  } map {
    case pat => x
  }

Exercise

for {
  x <- 2 to N
  y <- 2 to x
  if (x % y == 0)
} yield (x, y)

可以翻译为:

(2 to N) flatMap (x =>
  (2 to x) withFilter (y =>
    x % y == 0) map (y => (x, y)))

参考自 Principles of Reactive Programming

全文完 :)

目录
相关文章
|
2月前
|
索引
ES5常见的数组方法:forEach ,map ,filter ,some ,every ,reduce (除了forEach,其他都有回调,都有return)
ES5常见的数组方法:forEach ,map ,filter ,some ,every ,reduce (除了forEach,其他都有回调,都有return)
|
5月前
|
Python
高阶函数如`map`, `filter`, `reduce`和`functools.partial`在Python中用于函数操作
【6月更文挑战第20天】高阶函数如`map`, `filter`, `reduce`和`functools.partial`在Python中用于函数操作。装饰器如`@timer`接收或返回函数,用于扩展功能,如记录执行时间。`timer`装饰器通过包裹函数并计算执行间隙展示时间消耗,如`my_function(2)`执行耗时2秒。
34 3
WK
|
2月前
|
Python
map和filter的区别是什么
`map()`和`filter()`均为Python中的高阶函数,前者针对可迭代对象中的每个元素执行指定操作,如数值翻倍或字符串转大写;后者则筛选出符合条件的元素,例如仅保留偶数或非空字符串。两者均返回迭代器,并可通过`list()`等函数转换为所需的数据结构。具体使用时,应依据实际需求和场景选择合适的函数。
WK
18 1
WK
|
2月前
map和filter的区别是什么
在编程中,`map` 和 `filter` 是处理数组或集合时常用的两个函数。`map` 用于将每个元素通过指定函数转换后生成新的数组,而 `filter` 则根据条件筛选出符合条件的元素组成新数组。两者的主要区别在于:`map` 的返回数组长度与原数组相同,但元素被转换;`filter` 的返回数组长度可能不同,只包含符合条件的元素。
WK
30 2
|
2月前
|
JavaScript 前端开发
JavaScript 中 五种迭代数组的方法 every some map filter forEach
本文介绍了JavaScript中五种常用数组迭代方法:every、some、filter、map和forEach,并通过示例代码展示了它们的基本用法和区别。
|
3月前
|
JavaScript 前端开发 索引
JS中常用的数组迭代方法(filter,forEach,map,every,some,find,findIndex)
这段代码和说明介绍了JavaScript中数组的一些常用方法。函数接收三个参数:`item`(数组项的值)、`index`(项的位置,可选)和`array`(数组本身,可选)。示例展示了如何使用`filter()`过滤非空项、`forEach()`遍历数组、`map()`处理并返回新数组、`every()`检查所有元素是否满足条件、`some()`检查是否存在满足条件的元素、`find()`获取首个符合条件的元素值以及`findIndex()`获取其索引位置。这些方法都不会修改原数组。
JS中常用的数组迭代方法(filter,forEach,map,every,some,find,findIndex)
|
3月前
|
存储 算法 Java
Go 通过 Map/Filter/ForEach 等流式 API 高效处理数据
Go 通过 Map/Filter/ForEach 等流式 API 高效处理数据
|
3月前
|
分布式计算 Serverless 数据处理
|
4月前
|
人工智能 算法 大数据
算法金 | 推导式、生成器、向量化、map、filter、reduce、itertools,再见 for 循环
这篇内容介绍了编程中避免使用 for 循环的一些方法,特别是针对 Python 语言。它强调了 for 循环在处理大数据或复杂逻辑时可能导致的性能、可读性和复杂度问题。
52 6
算法金 | 推导式、生成器、向量化、map、filter、reduce、itertools,再见 for 循环
|
3月前
|
安全 Java API
Java 8 流库的魔法革命:Filter、Map、FlatMap 和 Optional 如何颠覆编程世界!
【8月更文挑战第29天】Java 8 的 Stream API 通过 Filter、Map、FlatMap 和 Optional 等操作,提供了高效、简洁的数据集合处理方式。Filter 用于筛选符合条件的元素;Map 对元素进行转换;FlatMap 将多个流扁平化合并;Optional 安全处理空值。这些操作结合使用,能够显著提升代码的可读性和简洁性,使数据处理更为高效和便捷。
125 0