一次迭代多个变量,重叠( slice::windows)或不重叠( slice::chunks)可能很有用.

这仅适用于切片;是否可以为迭代器执行此操作,为方便起见使用元组?

可以写下以下内容:

for (prev,next) in some_iter.windows(2) {
    ...
}

如果没有,它可以作为现有迭代器的特征实现吗?

TL; DR:在任意迭代器/集合上拥有块和窗口的最佳方法是首先将它收集到Vec中并迭代它.

在Rust中,所要求的确切语法是不可能的.

问题是在Rust中,函数的签名取决于类型,而不是值,并且存在Dependent Typing时,实现它的语言很少(很难).

这就是为什么块和窗口返回子切片的原因; & [T]中的元素数量不是类型的一部分,因此可以在运行时决定.

让我们假装你要求:for some_iter.windows(2)中的切片然后.

支持这片的存储在哪里?

它无法生存:

>在原始集合中,因为LinkedList没有连续的存储
>在迭代器中,由于Iterator :: Item的定义,没有可用的生命周期

因此,不幸的是,切片只能在后备存储是切片时使用.

如果接受动态分配,则可以使用Vec< Iterator :: Item>作为分块迭代器的项目.

struct Chunks<I: Iterator> {
    elements: Vec<<I as Iterator>::Item>,underlying: I,}

impl<I: Iterator> Chunks<I> {
    fn new(iterator: I,size: usize) -> Chunks<I> {
        assert!(size > 0);

        let mut result = Chunks {
           underlying: iterator,elements: Vec::with_capacity(size)
        };
        result.refill(size);
        result
    }

    fn refill(&mut self,size: usize) {
        assert!(self.elements.is_empty());

        for _ in 0..size {
            match self.underlying.next() {
                Some(item) => self.elements.push(item),None => break,}
        }
    }
}

impl<I: Iterator> Iterator for Chunks<I> {
    type Item = Vec<<I as Iterator>::Item>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.elements.is_empty() {
            return None;
        }

        let new_elements = Vec::with_capacity(self.elements.len());
        let result = std::mem::replace(&mut self.elements,new_elements);

        self.refill(result.len());

        Some(result)
    }
}

fn main() {
    let v = vec!(1,2,3,4,5);

    for slice in Chunks::new(v.iter(),2) {
        println!("{:?}",slice);
    }
}

将返回:

06001

精明的读者会意识到我偷偷地从窗户切换到了大块.

窗口更难,因为它多次返回相同的元素,这要求元素是克隆.此外,由于每次都需要返回完整的Vec,因此需要在内部保持Vec< Vec< Iterator :: Item>>.

这留给读者练习.

最后,关于性能的说明:所有这些分配都会受到伤害(特别是在Windows案例中).

最好的分配策略通常是分配一块内存然后实现(除非数量非常大,在这种情况下需要流式传输).

它在Rust中称为collect ::< Vec< _>>().

并且由于Vec具有块和窗口方法(通过实现Deref< Target = [T]>),因此您可以使用它:

for slice in v.iter().collect::<Vec<_>>().chunks(2) {
    println!("{:?}",slice);
}

for slice in v.iter().collect::<Vec<_>>().windows(2) {
    println!("{:?}",slice);
}

有时最好的解决方案是最简单的.

slice :: chunks / windows是否有等效的迭代器循环对,三元组等?的更多相关文章

  1. 挺好的一篇总结文(等有空时看看)

    最近几天的感受是,Swift并不像我上一篇表达自己初步看法的文章里所说的那样,相对于objc来说有更好的学习曲线。另外一种类型是复合类型,包括函数和多元组。它们在使用的时候不会被命名,而是由Swift内部自己定义。在Swift的世界中,一切看得到的东西,都一定属于某一种类型。这也正式Swift的类型的一种很常见的组织方式。而当我们检查到Array的时候,发生了一点神奇的事情。这里的原因其实在Apple的官方文档中有一些说明。

  2. Swift Array Slice

    之前在学习Swift的时候,了解过一下数组的用法,以为是非常了解了,实则不然。明明数组中有两个元素,但是为什么用subscript访问,却报错呢?所以,在用[0]访问slicedArray的时候,其实是越界的outofbounds!!!!

  3. 老司机带你深入浅出 Collection

    迭代器Iterator遵守Sequence协议。迭代器内部有一个称为Element的关联类型。标准库类型中的例子有String.CharacterView,这让字符串片段的使用更为方便。索引Index索引表示集合中的位置。因此,String.CharacterView.Index是一个不可见的值,指向字符串的内部存储缓冲区中的位置。索引距离IndexDistance索引距离是一个带符号的整型,表示两个索引之间的距离。索引范围Indices这是集合的indices属性的返回类型。如果数组的索引是一个整数类型

  4. 创建 Swift 自定义集合类

    在本文,你将学习用Swift的collection协议创建自定义集合类型。当文本结束,你会拥有一个强大的自定义集合类型,拥有Swift内置集合的所有功能。小于次的版本无法编译,因为Swift标准库发生了剧烈改变。在一个Set集合中,重复对象会被忽略。Swift提供了让Bag符合传统集合的所有工具。你需要先了解一下在Swift中,让一个对象变成集合需要做些什么。要理解什么是Swift集合,首先需要它继承的协议层次:Sequence协议表示类型支持排序、以迭代的方式访问其元素。

  5. swift – 使用依赖于元素类型的递归属性/方法扩展Collection

    –但调度已关闭:$1.flatCount不绑定到第二个递归版本,但总是绑定到第一个普通版本.也就是说,flatCount仅计算第一个嵌套级别.有没有办法以表达此功能的方式处理类型和/或调度?

  6. 数组 – Swift 2D数组通用扩展 – 访问第二维的问题

    我正在尝试将以下函数转换为2D数组的通用扩展.我特别难以指出如何指定约束以允许我访问第二个维度.这是一次失败的尝试:问题是编译器不知道你的扩展是用于2D数组–它只知道它是用于集合数组.因此,关联类型Indexdistance和Index不一定是Int.因此,解决方案是约束您的扩展,以便Element的Indexdistance和Index属于Int类型.这将允许您形成范围0..

  7. 数组 – 为什么Swift迭代器比数组构建慢?

    这意味着,不知何故,迭代生成器比在内存中构造新数组花费更多的时间,然后迭代它.令人难以置信的是,它甚至比同一程序的python实现慢约5-70%,随着输入的减少而恶化.Swift是用-O标志构建的.这里有三个测试用例1.小输入,混合;2.大输入,[Int]显性,3.大输入,Int显性:迅速蟒蛇生成器和数组构建器:迅速蟒蛇基准测试结果:迅速蟒蛇显然,Swift非常非常擅长构建数组.但是为什么它的发生器在某些情况下如此慢,甚至比Python慢?

  8. android – MarkerView走出图表的最后一点

    我正在使用MarkerView类在图表中显示标记视图.我创建的markerview布局包含两个textview,一个在另一个之下.我面临的问题是图表上最后一个点的标记视图是图表中的一半,而图表中的一半.下面的两张图片清楚地说明了问题:第一张图显示了图表中心点的标记视图,显示没有任何问题:第二个图像,如下所示,显示图表最后一个点的标记视图,它是图表中的一半.如何调整此标记视图以使其在图表区域内显示.Wiki不会为markerview声明任何自定义.还有更多自定义吗?

  9. android – 当app是后台FCM时,如何检索通知消息intent.getExtras()

    我正在使用FCM进行简单通知当应用程序处于前台时,一切正常.我在onMessageReceived方法中收到通知和数据消息.但是当应用程序处于后台时,我会在系统托盘中收到通知.当我点击控件时,它会转到主要活动.当我解析intent.getExtras();时,我只得到这个关键数据–google.sent_time,from,google.message_id,collapse_key.如何从intent.getExtras()获取系统托盘中可见的通知消息标题和消息?

  10. Android – 使用ORMLite DAO作为ContentProvider

    我旁边的同事真的非常想使用Ormlite,因为他不想自己编写任何映射.我知道atleap和Android-OrmliteContentProvider项目的存在.这些只为活动提供了一个光标,我的同事希望拥有模型列表或单个模型.这可以实现吗?和Contentprovider必须使用模型.但是,使用列表等仍然可以实现相同的功能吗?将事件传递给contentobservers等活动?

随机推荐

  1. static – 在页面之间共享数据的最佳实践

    我想知道在UWP的页面之间发送像’selectedItem’等变量的最佳做法是什么?创建一个每个页面都知道的静态全局变量类是一个好主意吗?

  2. .net – 为Windows窗体控件提供百分比宽度/高度

    WindowsForm开发的新手,但在Web开发方面经验丰富.有没有办法为Windows窗体控件指定百分比宽度/高度,以便在用户调整窗口大小时扩展/缩小?当窗口调整大小时,可以编写代码来改变控件的宽度/高度,但我希望有更好的方法,比如在HTML/CSS中.在那儿?

  3. 使用Windows Azure查询表存储数据

    我需要使用特定帐户吗?>将应用程序部署到Azure服务后,如何查询数据?GoogleAppEngine有一个数据查看器/查询工具,Azure有类似的东西吗?>您可以看到的sqlExpressintance仅在开发结构中,并且一旦您表示没有等效,所以请小心使用它.>您可以尝试使用Linqpad查询表格.看看JamieThomson的thispost.

  4. windows – SetupDiGetClassDevs是否与文档中的设备实例ID一起使用?

    有没有更好的方法可以使用DBT_DEVICEARRIVAL事件中的数据获取设备的更多信息?您似乎必须指定DIGCF_ALLCLASSES标志以查找与给定设备实例ID匹配的所有类,或者指定ClassGuid并使用DIGCF_DEFAULT标志.这对我有用:带输出:

  5. Windows Live ID是OpenID提供商吗?

    不,WindowsLiveID不是OpenID提供商.他们使用专有协议.自从他们的“测试版”期结束以来,他们从未宣布计划继续它.

  6. 如果我在代码中进行了更改,是否需要重新安装Windows服务?

    我写了一个Windows服务并安装它.现在我对代码进行了一些更改并重新构建了解决方案.我还应该重新安装服务吗?不,只需停止它,替换文件,然后重新启动它.

  7. 带有双引号的字符串回显使用Windows批处理输出文件

    我正在尝试使用Windows批处理文件重写配置文件.我循环遍历文件的行并查找我想要用指定的新行替换的行.我有一个’函数’将行写入文件问题是%Text%是一个嵌入双引号的字符串.然后失败了.可能还有其他角色也会导致失败.如何才能使用配置文件中的所有文本?尝试将所有“在文本中替换为^”.^是转义字符,因此“将被视为常规字符你可以尝试以下方法:其他可能导致错误的字符是:

  8. .net – 将控制台应用程序转换为服务?

    我正在寻找不同的优势/劣势,将我们长期使用的控制台应用程序转换为Windows服务.我们为ActiveMQ使用了一个叫做java服务包装器的东西,我相信人们告诉我你可以用它包装任何东西.这并不是说你应该用它包装任何东西;我们遇到了这个问题.控制台应用程序是一个.NET控制台应用程序,默认情况下会将大量信息记录到控制台,尽管这是可配置的.任何推荐?我们应该在VisualStudio中将其重建为服务吗?我使用“-install”/“-uninstall”开关执行此操作.例如,seehere.

  9. windows – 捕获外部程序的STDOUT和STDERR *同时*它正在执行(Ruby)

    哦,我在Windows上:-(实际上,它比我想象的要简单,这看起来很完美:…是的,它适用于Windows!

  10. windows – 当我试图批量打印变量时,为什么我得到“Echo is on”

    我想要执行一个简单的批处理文件脚本:当我在XP中运行时,它给了我预期的输出,但是当我在Vista或Windows7中运行它时,我在尝试打印值时得到“EchoisOn”.以下是程序的输出:摆脱集合表达式中的空格.等号(=)的两侧可以并且应该没有空格BTW:我通常在@echo关闭的情况下启动所有批处理文件,并以@echo结束它们,所以我可以避免将代码与批处理文件的输出混合.它只是使您的批处理文件输出更好,更清洁.

返回
顶部