在rust里面,我们可以对iter使用fold或者scan
如果使用fold,我们可以返回计算的最终结果,也只能返回最终结果
如果使用scan,我们可以在保留状态变量的同,对iter中的每一个元素进行计算并返回某个结果
我想问的是,是否存在一个介于这两者之间的函数,使我们可以针对部分iter元素返回计算结果而忽略其他元素
比如,现在有一个向量a,我希望获得一个向量b,满足:
(1)向量b的元素个数与向量a中等于0的元素个数相等
(2)向量b的第i个元素是a中第i-1个0到第i个0这些元素的和
差不多就是这个意思(不考虑数据溢出之类的情况)
/*input:*/ a=vec![1,2,0,3,4,0,5];
/*output:*/ assert_eq!(b,vec![3,7]);
我能想到的只有手写一个vec,然后调用for循环去一个个vec.push()
想问一下,能否用rust的迭代器,写一个更优美的解答
就比如
a.into_iter().???(0,|state,x|if(x==0){let ans=*state;*state=0;Some(ans)}else{*state+=x;None}).collect()
想知道有没有这样一个名叫???的函数(语法是scan的语法)
我试了一下,如果这里用scan,collect会失败。
let a:Vec<i32>=vec![1,2,-3,4,5];
let b:Vec<i32>=a.into_iter().scan(0,|state,x|{*state+=x;if(x>0){None}else{Some(*state)}}).collect();//才发现这里写错了……
println!("{:?}",b);//只会打印出[]
let a:Vec<i32>=vec![1,2,-3,4,5];
let mut c=a.into_iter().scan(0,|state,x|{*state+=x;if(x>0){None}else{Some(*state)}});
println!("{:?}",c.next());//None
println!("{:?}",c.next());//None
println!("{:?}",c.next());//Some(0)
println!("{:?}",c.next());//None
println!("{:?}",c.next());//None, iter在这一步用完
println!("{:?}",c.next());//None, iter在上一步其实已经用完了,但程序不知道
}
想知道有没有什么办法优雅地消费rust的迭代器
(如果最优雅的方法是手写for循环然后vec.push的话……就这样吧)
(现在我只会.into_iter().scan()然后.collect()/.for_each(),连手写迭代器trait都不会)
1
共 10 条评论, 1 页
评论区
写评论原来还有两层Some这样神奇的操作
学到了!
至于我用iter的原因很简单,用iter的话rust不会进行边界检查,而用下标的话rust有可能进行边界检查
虽然我不确定检查发生在编译还是运行阶段
但官方的ZCA都说了,iter“甚至略快一点”……
对以下内容的回复:
我写了一个,然而并不优雅,我以前也喜欢把循环用迭代器的方法写,但现在觉得还是应该挑选最合适的写法,有时候一堆迭代器搞来搞去,反而在花里胡哨中显得笨拙……
不过用迭代器看上去也不错,至少可读性挺好
对以下内容的回复:
我觉得这种直接用
for c in a.chars() {...}
更顺些,不用强求迭代器吧。实际上是个 parse 的动作。对以下内容的回复:
题解如下
对以下内容的回复:
仔细读了读官方的某些代码
好像可以直接map然后filter的……
对以下内容的回复:
看了一下str的split,好像可以直接判断字符串是否为空然后写进同一个函数了……
有点脏
先这么写吧……
对以下内容的回复:
学到了
以后或许会有用。
不过……目前我遇到的问题跟这个关系不太大
可能是我抽象的时候弄错了什么。
提出这个问题的原因是今天Leetcode的每日一题。
我在想,如果开一个栈存节点,然后把字符串处理成(减号个数,数值)这种格式的迭代器
之后我们只需要比较减号个数与栈的大小。
若减号个数等于栈的大小则新节点为原节点的左叶子节点,并将新节点入栈。
否则在栈中pop元素直到栈大小等于减号个数,此时将新节点设为栈顶元素右叶子节点,并将新节点入栈。
(减号个数大于栈的大小可以panic!)
这个想法直接死在了第一步……
不过经你提醒,我至少可以用split两次,一次切数字,一次切减号
但总觉得这样多遍历了一次字符串……虽然有点强迫症地不太喜欢,但至少题目能做了……
多谢~
对以下内容的回复:
针对你的需求可以用
slice::split
,不过不是你期望的那种实现方式。