Kotlin map flatten flatMap 区别

目录

  • map
  • flatten
  • flatMap

map

The mapping transformation creates a collection from the results of a function on the elements of another collection.

  如上面引用的官方文档所言,map函数的功能就是对于调用的Collection的每个元素,应用一个Transformation,然后返回一个新的Collection。官方的示例用法如下:

	val numbers = setOf(1, 2, 3)
	println(numbers.map { it * 3 })
	// return [3, 6, 9]	

  map这个函数,被很多人翻译为“遍历”,我觉得不太恰当。诚然,该函数的确会对调用函数的Collection每个元素进行遍历,但是其主要功能是对每个元素进行一个变换,然后返回变换后的新的Collection

  我觉得更好的翻译应该是“映射”,即将原Collection的每个元素映射为一个新的元素,并且构成一个新的Collection。在实际应用中,这种映射可能存在以下几种情况:

	// case 1
	collection.map { it.property }
	// case 2
	collection.map { it * 3 }
	// case ...

  第一种情况,就是将原元素,映射为其属性。如此返回的新Collection,实际上就是由每个元素对应的属性所构成的。

  第二种情况,就是将原元素,映射为其调用times(3)函数的返回值,由每个元素的如此的返回值,构成一个新的Collection

flatten

If you operate nested collections, you may find the standard library functions that provide flat access to nested collection elements useful.

  根据上述官方的定义,flatten函数的功能其实就是“展开”,即将嵌套的Collection,展开为最底层的元素。官方示例如下:

	val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5, 6), setOf(1, 2))
	println(numberSets.flatten())
	// return [1, 2, 3, 4, 5, 6, 1, 2]

  注意这个函数应该只能用于直接嵌套的情况,亦即由Collection组成的Collection。而对于间接嵌套的情况,例如一个由对象构成的Collection,每个对象包含一个Collection类型的属性,则需要用到下面的flatMap函数。

flatMap

  flatMap函数的词根是 map,而前缀才是 flat,因此是映射基础上的展开。实际上可以按照次序先后拆分为一个map函数和一个flatten函数。即先对调用的Collection进行映射,生成一个新的Collection,然后再对新生成的Collection的每个(Collection)元素进行展开。

  例如我们现在有两个类,Player是游戏的角色,Item是装备。两个类定义如下:

data class Player(
    val name: String,			// 角色名
    val items: List<Item>		// 装备列表
)

data class Item(
    val name: String,			// 装备名
    val damage: Int,			// 伤害值
    val defense: Int			// 防御值
)

  假设我们要获取每个角色的所有装备,即每个Player的所有Item,那么直接使用flatten函数是不行的,必须要使用flatMap函数。示例代码如下:

    val itemList1 = listOf(Item("泰阿剑", 86, 0), Item("纯钧剑", 102, 0))
    val itemList2 = listOf(Item("玄晶甲", 0, 48), Item("浸血甲", 0, 68))
    val player1 = Player("剑侍", itemList1)
    val player2 = Player("豪杰", itemList2)
    
    val playerList = listOf(player1, player2)
    
    println(playerList.flatMap { it.items })
    // 等价于
    // println(playerList.map { it.items }.flatten())

  其中,playerList.flatMap { it.items }playerList.map { it.items }.flatten()在效果上是等价的。

你可能感兴趣的:(Kotlin,kotlin)