Sum of Unique Elements

关于 1748 题 Sum of Unique Elements 的 Rust 的解法。打了一个月 DNF 增幅失败脱坑,可以回归正常(误,还是打游戏爽)的生活节奏。

Description

You are given an integer array nums. The unique elements of an array are the elements that appear exactly once in the array.

Return the sum of all the unique elements of nums.

Example 1:

Input: nums = [1,2,3,2] Output: 4 Explanation: The unique elements are [1,3], and the sum is 4.

Example 2:

Input: nums = [1,1,1,1,1] Output: 0 Explanation: There are no unique elements, and the sum is 0.

Example 3:

Input: nums = [1,2,3,4,5] Output: 15 Explanation: The unique elements are [1,2,3,4,5], and the sum is 15.

Solutions

Rust 实现:

rust
1pub fn sum_of_unique(nums: Vec<i32>) -> i32 {
2    nums.into_iter()
3        .fold(HashMap::new(), |mut acc, v| {
4            *acc.entry(v).or_insert(0) += 1;
5            acc
6        })
7        .into_iter()
8        .filter_map(|(k, v)| if v == 1 { Some(k) } else { None })
9        .sum::<i32>()
10}

TypeScript 实现:

ts
1function sumUnique(nums: number[]): number {
2    const counts = nums.reduce((acc: Map<number, number>, v: number) => {
3        acc.set(v, (acc.get(v) || 0) + 1);
4        return acc;
5    }, new Map<number, number>());
6
7    return Array.from(counts)
8        .filter(([_, v]) => v === 1)
9        .reduce((acc: number, [k, _]: [number, number]) => acc + k, 0);
10}

fold 和 acc 的名词解释

fold 函数在 Rust 中的功能与 reduce 在许多其他编程语言(如 JavaScript、Python 等)中的功能是相同的。fold 是一个将所有元素通过某种方式组合在一起的函数,通常用于从一个集合中生成一个单一的值。

在这个特定的代码示例中,fold 用于创建一个 HashMap,其中的每个键值对是 nums 中的元素及其出现的次数。

acc 通常是 "accumulator" 的缩写,指的是在 foldreduce 或类似的函数中用于累积结果的变量。在这个情况下,acc 是一个 HashMap,用于在迭代过程中存储每个元素及其出现次数。

accumulator 的解释

"Accumulator"在计算机科学和编程中通常用来表示一个在循环或迭代过程中累积(或收集)值的变量。在某些上下文中,它也可以被称为"reducer"或"aggregator"。

例如,在循环中,你可能有一个变量,你在每次循环迭代时都会增加它的值,这个变量就可以被看作是一个累加器。同样,你可能有一个列表或数组,你在每次迭代中都会向其中添加新的元素,这个列表或数组也可以被看作是一个累加器。

在你提供的那段Rust代码中,acc就是一个累加器,表示的是一个正在被构建的 HashMap。在每次迭代中,都会向这个 HashMap 中添加一个新的键值对,或者更新一个已存在的键值对的值。

filter_map 和 filter

filter_mapfilter 都是 Rust 中的迭代器方法,用于过滤集合中的元素。它们的主要区别在于,filter_map 允许在过滤元素的同时对元素进行一些变换,而 filter 只进行过滤操作。

具体来说:

  • filter 方法接受一个闭包,这个闭包接受一个元素作为参数,并返回一个布尔值。如果闭包返回 true,那么该元素就会被包含在最终的结果中;如果返回 false,那么元素将被排除出结果。
  • filter_map 方法也接受一个闭包,但这个闭包返回的是一个 Option。如果闭包返回 Some(value),那么 value 就会被包含在最终的结果中;如果返回 None,那么元素将被排除出结果。在处理元素并返回 Some(value) 时,可以对元素进行一些变换。

所以说,filter_mapfilter 的基础上提供了更大的灵活性,因为你可以在过滤元素的同时对元素进行变换。然而,如果你只需要过滤元素,而不需要进行任何变换,那么使用 filter 就足够了。

原始的 Rust 代码:

rust
1nums.into_iter()
2        .fold(HashMap::new(), |mut acc, v| {
3            *acc.entry(v).or_insert(0) += 1;
4            acc
5        })
6        .into_iter()
7        .filter_map(|(k, v)| if v == 1 { Some(k) } else { None })
8        .sum::<i32>()

filter 替换 filter_map 后的代码:

rust
1nums.into_iter()
2        .fold(HashMap::new(), |mut acc, v| {
3            *acc.entry(v).or_insert(0) += 1;
4            acc
5        })
6        .into_iter()
7        .filter(|&(_, v)| v == 1)
8        .map(|(k, _)| k)
9        .sum::<i32>()

在新代码中,我先使用 filter 过滤出只出现一次的元素,然后用 map 提取出这些元素的值(k),最后将这些值相加。