当前位置: 首页 > article >正文

【Rust Iterator 之 fold,map,filter,for_each】

Rust Iterator 之 fold,map,filter,for_each

  • 前言
  • map
  • for_each
    • 通过源码看for_each
  • fold
  • filter
  • 总结


前言

在Iterator 一文中,我们提到过Iterator时惰性的,也就是当我们将容器转换成迭代器时不会产生任何的迭代行为,所以在使用时开发者还需要将迭代器与消费者适配器共同使用。


map

比较常见的例子是map方法,map在使用时如果开发者不使用消费者适配器,则run时不会发生任何的事情并且在编译期间会收到报错。
代码示例:

fn usemapmethod() {
    let mut v = vec![1, 2, 3, 5];
    let vv = v.iter().map(|x| *x + 1);
    println!("{:?}", vv);
}
fn main() {
    usemapmethod();
}

上述代码使用了map想要使用闭包将每一个元素加1,但是没有使用消费者适配器,造成的结果就是打印的结果将与v中数据完全一致,因为map并没有执行,如果想要让其正确执行,需要配合消费者适配器,如下:

fn usemapmethod() {
    let mut v = vec![1, 2, 3, 5];
    let vv: Vec<_> = v.iter().map(|x| *x + 1).collect();
    println!("{:?}", vv);
}
fn main() {
    usemapmethod();
}

for_each

for_each 如字面意思,遍历迭代器,处理数据,与map不同的是,它不需要消费者适配器,同时与map的返回值不同,它只返回(),上代码:

use std::collections::HashMap;
fn usemapmethod() {
    let v = vec![1, 2, 3, 5];
    let mut mymap = HashMap::new();
    let _ = v.iter().for_each(|x| {
        mymap.insert(*x, *x + 1);
    });
    println!("{:?}", mymap);
}
fn main() {
    usemapmethod();
}

可以看到,在处理时我们直接将返回值丢弃,因为不同于消费者适配器返回的结果,我们通常不会接收for_each的返回结果,因为通常没有什么意义。

通过源码看for_each


            // We override the default implementation, which uses `try_fold`,
            // because this simple implementation generates less LLVM IR and is
            // faster to compile.
            #[inline]
            fn for_each<F>(mut self, mut f: F)
            where
                Self: Sized,
                F: FnMut(Self::Item),
            {
                while let Some(x) = self.next() {
                    f(x);
                }
            }

可以看到,不同于map,在for_each 内部通过一个while循环直接进行了遍历。

fold

字面意思折叠,通过命名大概能猜测出fold的具体用途,既将通过 闭包处理的数据最后叠加到一起。

use std::collections::HashMap;
fn usemapmethod() {
    let v = vec![1, 2, 3, 4, 6, 5];
    let result = v
        .iter()
        .fold(0, |acc, num| if num % 3 == 0 { acc + num } else { acc });

    println!("{}", result)
}
fn main() {
    usemapmethod();
}

filter

按照特定的条件过滤符合的原有数据,当我们使用fold传入的acc值是0的时候,通常我们可以通过filter+sum的方式实现相同的逻辑,那么具体在实际使用过程中,应该如何挑选这里并没有什么约定俗成,选择自己适合并且容易理解的方式就选择filter+sum这通常满足我们的简单过滤和累计,fold试用于相对更复杂一点的逻辑。( 个人理解,当然你可以使用不同的组合方式创造出适合自己业务逻辑的代码)

fn usemapmethod() {
    let v = vec![1, 2, 3, 4, 6, 5];
    let vv: i32 = v.iter().filter(|n| *n % 3 == 0).sum();

    println!("{}", vv)
}
fn main() {
    usemapmethod();
}


总结

在实际开发中会遇到各种各样的需求,熟练掌握method并理解其中的意义和作用,可以让我们更加rusty。

“积跬步,行万里。”


http://www.kler.cn/a/410693.html

相关文章:

  • JavaScript的基础数据类型
  • leetcode hot100【LeetCode 238.除自身以外数组的乘积】java实现
  • Web3 游戏周报(11.17 - 11.23)
  • uniapp 地图移入的快,高亮显示两个
  • Python和C++急性损伤空间结构
  • C#对INI配置文件进行读写操作方法
  • 论文阅读 - Causality Inspired Representation Learning for Domain Generalization
  • 计算机国际会议中proceedings,conference,paper,workshop,demo的区别是什么?
  • SpringBoot集成Minio实现上传凭证、分片上传、秒传和断点续传
  • python-爬虫入门指南
  • docker私有仓库的介绍以及 Docker registry 安装
  • HDMI数据传输三种使用场景
  • Spring源码(十三):Spring全系列总结
  • 图论基础知识
  • 零售电子商务数仓搭建之维度建模
  • openssl颁发包含主题替代名的证书–SAN
  • 微软Ignite 2024:建立一个Agentic世界!
  • PyQt的安装和再PyCharm中的配置
  • 机器学习—添加数据
  • 【AIGC】如何准确引导ChatGPT,实现精细化GPTs指令生成
  • C语言中宏的常见用法总结
  • 如何开发一个脚手架
  • 创建HTTPS网站
  • 《AI大模型开发笔记》——Prompt提示词最佳实践
  • 为什么DDoS防御很贵?
  • Js-对象-04-Array