我遇到了这个竞争性的编程问题:
nums
是整数(长度为n
)的向量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
方法。您将如何完成这项任务?
答案 0 :(得分:4)
Kotlin的reduce
以迭代器的第一项作为起点,而Rust的fold
和try_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(()),
})
或者因为我们从向量开始,可以对其进行索引:
nums[1..]
.iter()
.zip(ops.iter())
.try_fold(nums[0], |a, (b, op)| match op {
'+' => Ok(a + b),
'-' => Ok(a - b),
_ => Err(()),
});
答案 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之类的板条箱。