Kotlin 函数式编程保留 List 中前一个对象的引用
Kotlin functional programming keep reference of previous object in List
我有一个 Person 对象的列表,这些对象按照它们在列表中出现的顺序与配偶关系相互关联。
enum class Gender {
MAN, WOMAN
}
data class Person(val name: String, val age: Int, val gender: Gender)
在列表中,每个性别为 MAN 的人都是以下性别为 WOMAN 的人的配偶(反之亦然),并且列表中的每个条目后面都是交替的性别,MAN 性别是第一个。
理想情况下,该列表应该像 [MAN, WOMAN, MAN, WOMAN, MAN, WOMAN]
(显然它将是一个 Person 对象列表,为简单起见,我在此处放置了一个 Gender 列表),但它也可以像 [WOMAN, MAN, WOMAN, MAN, WOMAN, MAN]
。在后一种情况下,第一个出现的女人是最后一个出现的男人的配偶。
如何使用函数式编程在 kotlin 中处理第二种情况。
我目前的方法包括检查第一个人是否有性别女性,然后我删除列表中的第一个和最后一个对象,然后将它们添加到最后,但这不是一个完整的函数式编程解决方案。
有人可以指导我吗?
谢谢
全功能方法是什么意思?
与您提到的类似,您可以通过这样的简单语句来修复顺序:
val correctList = if(list.first().gender == MAN) list else list.drop(1) + list.first()
如果你想要一个更通用的方法,你可以这样做:
// separate the people into a list of gender=MAN and a list of everyone else
// the result is a Pair, so I'm destructuring that into two variables
val (men, women) = people.partition { it.gender == MAN }
// use zip to take a person from each list and combine them into a list of pairs
men.zip(women)
// use flatMap to turn each pair into a list of two people
// just using map would create a list of lists, flatMap flattens that into
// a single list of people, alternating gender=MAN, gender=WOMAN
.flatMap { it.toList() }
这样,原始列表的排序方式无关紧要,它可以从任何元素开始,并且您可以将不同的类型完全混合 - BABBAABA
仍然会显示为 ABABABAB
.所以这是合并混合数据流的通用方法 - partition
将它们分成几组,而 zip
允许您从每个组中取出一个元素并对它们进行处理。
在这里,我只是让 zip
创建 Pair
,然后 flatMap
将它们变回有序列表(如果这是您想要的)。你也可以在每一对上做一个 forEach
(比如你想在每个 Person
上设置一个值到 link 它们彼此),或者 zip
可以采取还有一个转换函数。
当其中一个列表用完时 zip
也会终止(例如,对于 AAA
和 BB
你会得到两对)所以这适用于生成完整的元素对 -如果你还需要在没有“伙伴”的情况下处理元素,你需要做更多的工作
我有一个 Person 对象的列表,这些对象按照它们在列表中出现的顺序与配偶关系相互关联。
enum class Gender {
MAN, WOMAN
}
data class Person(val name: String, val age: Int, val gender: Gender)
在列表中,每个性别为 MAN 的人都是以下性别为 WOMAN 的人的配偶(反之亦然),并且列表中的每个条目后面都是交替的性别,MAN 性别是第一个。
理想情况下,该列表应该像 [MAN, WOMAN, MAN, WOMAN, MAN, WOMAN]
(显然它将是一个 Person 对象列表,为简单起见,我在此处放置了一个 Gender 列表),但它也可以像 [WOMAN, MAN, WOMAN, MAN, WOMAN, MAN]
。在后一种情况下,第一个出现的女人是最后一个出现的男人的配偶。
如何使用函数式编程在 kotlin 中处理第二种情况。 我目前的方法包括检查第一个人是否有性别女性,然后我删除列表中的第一个和最后一个对象,然后将它们添加到最后,但这不是一个完整的函数式编程解决方案。
有人可以指导我吗?
谢谢
全功能方法是什么意思?
与您提到的类似,您可以通过这样的简单语句来修复顺序:
val correctList = if(list.first().gender == MAN) list else list.drop(1) + list.first()
如果你想要一个更通用的方法,你可以这样做:
// separate the people into a list of gender=MAN and a list of everyone else
// the result is a Pair, so I'm destructuring that into two variables
val (men, women) = people.partition { it.gender == MAN }
// use zip to take a person from each list and combine them into a list of pairs
men.zip(women)
// use flatMap to turn each pair into a list of two people
// just using map would create a list of lists, flatMap flattens that into
// a single list of people, alternating gender=MAN, gender=WOMAN
.flatMap { it.toList() }
这样,原始列表的排序方式无关紧要,它可以从任何元素开始,并且您可以将不同的类型完全混合 - BABBAABA
仍然会显示为 ABABABAB
.所以这是合并混合数据流的通用方法 - partition
将它们分成几组,而 zip
允许您从每个组中取出一个元素并对它们进行处理。
在这里,我只是让 zip
创建 Pair
,然后 flatMap
将它们变回有序列表(如果这是您想要的)。你也可以在每一对上做一个 forEach
(比如你想在每个 Person
上设置一个值到 link 它们彼此),或者 zip
可以采取还有一个转换函数。
当其中一个列表用完时 zip
也会终止(例如,对于 AAA
和 BB
你会得到两对)所以这适用于生成完整的元素对 -如果你还需要在没有“伙伴”的情况下处理元素,你需要做更多的工作