在Rust中,有什么方法可以替代Kotlin的“ reduce”操作?

时间:2019-02-27 04:03:28

标签: collections functional-programming rust reduce

我遇到了这个竞争性的编程问题:

  1. nums是整数(长度为n)的向量
  2. ops是包含+-(长度n-1)的字符串的向量

可以通过Kotlin中的reduce操作来解决,如下所示:

val op_iter = ops.iterator();
nums.reduce {a, b ->
    when (op_iter.next()) {
        "+" -> a+b
        "-" -> a-b
        else -> throw Exception()
    }
}

reduce被描述为:

  

从第一个元素开始累加值,并从左到右对当前累加器值和每个元素应用运算。

似乎Rust向量没有reduce方法。您将如何完成这项任务?

2 个答案:

答案 0 :(得分:4)

Kotlin的reduce以迭代器的第一项作为起点,而Rust的foldtry_fold让您指定自定义起点。

这里等同于Kotlin代码:

let mut it = nums.iter().cloned();
let start = it.next().unwrap();
it.zip(ops.iter()).try_fold(start, |a, (b, op)| match op {
    '+' => Ok(a + b),
    '-' => Ok(a - b),
    _ => Err(()),
})

Playground

或者因为我们从向量开始,可以对其进行索引:

nums[1..]
    .iter()
    .zip(ops.iter())
    .try_fold(nums[0], |a, (b, op)| match op {
        '+' => Ok(a + b),
        '-' => Ok(a - b),
        _ => Err(()),
    });

Playground

答案 1 :(得分:0)

Rust 1.48中没有reduce。在许多情况下,您可以使用fold模拟它,但是请注意,这些函数的语义是不同的。如果迭代器为空,则fold将返回初始值,而reduce将返回None。例如,如果要对所有元素执行乘法运算,则为空集获取结果1不太合逻辑。

Rust确实具有一个fold_first函数,它等效于Kotlin的reduce,但是它还不稳定。 main discussion是关于命名的。如果您每晚都可以使用Rust,这是一个安全的选择,因为该功能被删除的可能性很小。在最坏的情况下,名称将被更改。如果您需要稳定的Rust,则可以使用fold,如果对空集不满意,可以使用$ cat tst.awk /^build:/ { f=1 } !NF { prt(); f=0 } { print; prev=$0 } END { prt() } function prt() { if (f) { sub(/[^[:space:]].*/,"",prev) print prev "number: 123" } } 。如果没有,那么您将必须实现它,或找到一个诸如reduce之类的板条箱。