Rust 如何使用默认值压缩两个长度不等的迭代器?

Rust 如何使用默认值压缩两个长度不等的迭代器?,rust,iterator,Rust,Iterator,我试图压缩两个长度不等的迭代器,它只在两者都有值时返回,而忽略最长迭代器中的其余部分 fn main(){ 设num1=vec![1,2]; 设num2=vec![3]; 对于num1.iter().rev().zip(num2.iter().rev())中的i{ println!(“{:?}”,i); } } 这将返回(2,3)。如何使其返回: (2,3) (1,0)//此处默认为0。 还有其他方法吗?您可以使用板条箱提供的邮政编码 使用itertools::{ Itertools, Ei

我试图压缩两个长度不等的迭代器,它只在两者都有值时返回,而忽略最长迭代器中的其余部分

fn main(){
设num1=vec![1,2];
设num2=vec![3];
对于num1.iter().rev().zip(num2.iter().rev())中的i{
println!(“{:?}”,i);
}
}
这将返回
(2,3)
。如何使其返回:

(2,3)
(1,0)//此处默认为0。

还有其他方法吗?

您可以使用板条箱提供的
邮政编码

使用itertools::{
Itertools,
EitherBoth::*,
};
fn main(){
设num1=vec![1,2];
设num2=vec![3];
对于num1.iter().rev().zip_最长(num2.iter().rev())中的配对{
配对{
两者(l,r)=>println!(“({:?},{:?})”,l,r,
左(l)=>println!(“({:?},0)”,l),
右(r)=>println!(“(0,{:?})”,r),
}
}
}
这将产生以下输出:

(2, 3)
(1, 0)

一旦其中一个迭代器停止生成值,Zip就会停止。如果知道哪一个最长,可以使用默认值填充较短的一个:

use std::iter;

fn main() {
    let longer = vec![1, 2];
    let shorter = vec![3];

    for i in longer
        .iter()
        .rev()
        .zip(shorter.iter().rev().chain(iter::repeat(&0)))
    {
        println!("{:?}", i);
    }
}

如果您不知道哪一个最长,那么应该使用itertools,因为。

关键是检测一个迭代器比另一个迭代器短,您可以在vector实现中执行此操作,但一般的解决方案是使用自定义的
.zip()

已经提供了一个通用解决方案:

这要求您每次都编写闭包,如果您经常需要此功能,可以使用
.zip_default()
在迭代器上实现自定义特征,其中
a
B
实现:

使用std::default::default;
使用std::iter::Fuse;
pub-trait-MyIterTools:迭代器{
fn zip_默认值(self,other:J)->ZipDefault
哪里
J:迭代器,
自我:大小,
{
ZipDefault::新建(self,other.into_iter())
}
}
#[派生(克隆、调试)]
pub结构ZipDefault{
i:保险丝,
j:保险丝,
}
impl-ZipDefault
哪里
I:迭代器,
J:迭代器,
{
fn新的(i:i,j:j)->Self{
自我{
i:i.保险丝(),
j:j.保险丝(),
}
}
}
ZipDefault的impl迭代器
哪里
T:迭代器,
U:迭代器,
答:违约,
B:违约,
{
类型项=(A,B);
fn下一步(&mut self)->选项{
匹配(self.i.next(),self.j.next()){
(一些(a),一些(b))=>一些(a,b)),
(Some(a),None)=>Some((a,B::default()),
(无,部分(b))=>Some((A::default(),b)),
(无,无)=>无,
}
}
}
T的impl MyIterTools,其中T:Iterator{}
fn main(){
设num1=vec![1,2];
设num2=vec![3];
对于num1中的i
.国际热核实验堆(iter)
.copied()
.rev()
.zip_默认值(num2.iter().copied().rev())
{
println!(“{:?}”,i);
}
}
使用itertools,我们可以委托一些逻辑:

使用std::default::default;
使用itertools::itertools;
使用itertools::ZipLongest;
使用itertools::eitherborboth::{Both,Left,Right};
pub-trait-MyIterTools:迭代器{
fn zip_默认值(self,j:j)->ZipDefault
哪里
自我:大小,
J:迭代器,
{
ZipDefault::new(self,j.into_iter())
}
}
#[派生(克隆、调试)]
pub结构ZipDefault{
内部:ZipLongest,
}
impl-ZipDefault
哪里
I:迭代器,
J:迭代器,
{
fn新的(i:i,j:j)->Self{
自我{
内部:i.zip_最长(j),
}
}
}
ZipDefault的impl迭代器
哪里
T:迭代器,
U:迭代器,
答:违约,
B:违约,
{
类型项=(A,B);
fn下一步(&mut self)->选项{
匹配self.inner.next(){
两者(a,b)=>一些((a,b)),
左(a)=>Some((a,B::default()),
右(b)=>Some((A::default(),b)),
}
}
fn大小提示(&self)->(使用,选项){
self.inner.size_hint()
}
}
T的impl MyIterTools,其中T:Iterator{}
fn main(){
设num1=vec![1,2];
设num2=vec![3];
对于num1中的i
.国际热核实验堆(iter)
.copied()
.rev()
.zip_默认值(num2.iter().copied().rev())
{
println!(“{:?}”,i);
}
}

如果您可以获得迭代器的长度,就像在本例中一样,一种快速而肮脏的方法可能是:

使用std::iter::repeat;
fn main(){
设a=vec![1,2,3];
设b=vec![4,5,6,7];
因为我在一个
.国际热核实验堆(iter)
.rev()
.chain(repeat(&0).take(b.len().saturating_sub(a.len()))
zip先生(
b、 iter()
.rev()
.chain(repeat(&0).take(a.len().saturating_sub(b.len())),
)
{
println!(“{:?}”,i);
}
}
您还可以使用以下方法实现包含
zip\u default()
的特征:


pub-trait-MyIterTools:ExactSizeIterator{
fn zip_默认值(self,j:j)->ZipDefault
哪里
自我:大小,
J:迭代器,
J::输入者:精确大小运算符,
Y:默认+克隆,
{
ZipDefault::new(self,j.into_iter())
}
}
#[派生(克隆、调试)]
pub结构ZipDefault<
I:精确大小的运算符,
J:精确大小的运算器,
X:默认+克隆,
Y:默认+克隆,
> {
内部:拉链,
}
恳求<
I:精确大小的运算符,
J:精确大小的运算器,
X:默认+克隆,
Y:默认+克隆,
>ZipDefault
{
fn新(a:I,b:J)->自我{
设a_len=a.len();
设b_len=b.len();
自我{
内部:a
.chain(repeat(X::default()).take(b_len.saturating_sub(a_len)))
.zip(b.chain(repeat(Y::default()).take(a_len.saturating_sub(b_len))),
}
}
}
恳求<
I:精确大小的运算符,
J:精确大小的运算器,
X:默认+克隆,
Y:默认+克隆,
>ZipDefault的迭代器
{
类型项=(X,Y);
fn下一步(&mut self)->选项{
use itertools::EitherOrBoth::{Both, Left, Right};
use itertools::Itertools;

fn main() {
    let num1 = vec![1, 2];
    let num2 = vec![3];

    for i in num1
        .iter()
        .rev()
        .zip_longest(num2.iter().rev())
        .map(|x| match x {
            Both(a, b) => (a, b),
            Left(a) => (a, &0),
            Right(b) => (&0, b),
        })
    {
        println!("{:?}", i);
    }
}