Scala中元组列表处理(第四部分):手动拆分奇偶年龄子列表
Hey there! I totally get where you’re coming from—switching from Python’s flexible list handling to Scala’s functional approach can feel a bit jarring at first, especially when you’re trying to avoid built-in methods like partition or filter. Let’s walk through how to solve this step by step, with code that feels intentional and aligns with Scala’s style.
First, let’s start with a sample list of person tuples (name, age) like you mentioned:
// 模拟人员元组列表 val people = List(("Alice", 24), ("Bob", 31), ("Charlie", 28), ("David", 19), ("Eve", 30))
The key here is to use foldLeft—a functional tool that lets us iterate through the list while accumulating two separate lists (one for even ages, one for odd ages). Think of it like manually looping through each element and deciding which list to add it to, but in a pure, immutable way.
Here’s the code:
// 用foldLeft累积两个列表,初始值是两个空列表的元组 val (evenAgesUnordered, oddAgesUnordered) = people.foldLeft((List.empty[(String, Int)], List.empty[(String, Int)])) { // 模式匹配每个元素和当前的累积结果 case ((evens, odds), person @ (_, age)) => if (age % 2 == 0) { // 年龄偶数,加到even列表头部 (person :: evens, odds) } else { // 年龄奇数,加到odd列表头部 (evens, person :: odds) } } // 因为::是往列表头部添加元素,所以结果会是逆序的,如果需要保持原列表的顺序,反转一下即可 val evenAges = evenAgesUnordered.reverse val oddAges = oddAgesUnordered.reverse // 最后整合成要求的List[evenList, oddList]格式 val finalResult = List(evenAges, oddAges)
Let me break this down a bit:
foldLeftstarts with an initial state: a tuple of two empty lists.- For each person in the original list, we check if their age is even or odd.
- We use
::to prepend the person to the corresponding list (this is more efficient than appending with:+in Scala). - Since prepending reverses the order, we call
reverseon each list if we want to keep the same order as the original list. If order doesn’t matter, you can skip this step!
If you prefer a more "Python-like" mutable approach (though it’s not the most idiomatic Scala), you could also use var to declare two empty lists and loop through each person, but the foldLeft method is far more aligned with Scala’s functional programming principles.
For example, the mutable version would look like this:
var evens = List.empty[(String, Int)] var odds = List.empty[(String, Int)] for ((name, age) <- people) { if (age % 2 == 0) evens = evens :+ (name, age) else odds = odds :+ (name, age) } val finalResult = List(evens, odds)
Either way, you get the split you need without using filter or partition. Hope this helps you wrap your head around Scala’s list handling!
内容的提问来源于stack exchange,提问作者Yuva

