Ale*_*lov 4 iteration mapping filtering file rust
我有这个功能:
fn folders(dir: &Path) -> Result<Vec<PathBuf>, io::Error> {
fs::read_dir(dir)?
.into_iter()
.map(|x| x.map(|entry| entry.path()))
.collect()
}
Run Code Online (Sandbox Code Playgroud)
其实是从这里借来的。功能正常;不幸的是,我不太明白它是如何工作的。
Ok(["/home/ey/dir-src/9", "/home/ey/dir-src/11", "/home/ey/dir-src/03 A Letter of Explanation.mp3", "/home/ey/dir-src/02 Egyptian Avenue.mp3", "/home/ey/dir-src/alfa", "/home/ey/dir-src/10"])
Run Code Online (Sandbox Code Playgroud)
测试输出显示目录和文件,正如它应该的那样。我不知道在哪里放置文件/目录过滤。我不明白为什么映射里面的映射:它不只是一个简单的路径列表吗?这个表达式中到底发生了什么?
更新:
fn folders(dir: &Path) -> Result<Vec<PathBuf>, io::Error> {
fs::read_dir(dir)?
.into_iter()
.map(|x| x.map(|entry| entry.path()))
.filter(|x| {x.as_ref().map(|entry| entry); true})
.collect()
}
Run Code Online (Sandbox Code Playgroud)
插入一个简单的过滤器(总是true)。它至少正在编译,但我仍然不知道应该如何使用entry文件/目录检查。对不起 :)
让我们一步一步地遍历链条。
fs::read_dir(dir)?
Run Code Online (Sandbox Code Playgroud)
创建目录的读取句柄,Err如果发生,则立即传播情况,如果没有,unwrap则成功(即?操作符)
.into_iter()
Run Code Online (Sandbox Code Playgroud)
将此读取句柄转换为迭代器Result<DirEntry>
.map(|x|
x.map(|entry| entry.path())
)
Run Code Online (Sandbox Code Playgroud)
path()如果结果是实际的 ,则这会在迭代器的每个元素上调用该方法DirEntry。因为迭代器元素Result<DirEntry>不仅仅是DirEntry,所以第二个元素map()可以让您干净地处理这个问题。您将看到输出中看到的路径
.collect()
Run Code Online (Sandbox Code Playgroud)
将此迭代器转回由类型提示定义的结构(此处为向量)
过滤部分可以在调用之前或之后实现,以map()将条目转换为PathBuf. 如果您需要根据元素本身而不是其PathBuf前面的 , 进行过滤。如果可以基于 进行过滤PathBuf,则在其之后进行过滤。
组合器函数的使用filter()很简单 - 你给它一个闭包,它会将它应用到每个元素。如果闭包的返回值为true,则保留该元素。如果为 false,则删除该元素。
这是一个仅返回目录的示例:
fn folders(dir: &Path) -> Result<Vec<PathBuf>, io::Error> {
Ok(fs::read_dir(dir)?
.into_iter()
.filter(|r| r.is_ok()) // Get rid of Err variants for Result<DirEntry>
.map(|r| r.unwrap().path()) // This is safe, since we only have the Ok variants
.filter(|r| r.is_dir()) // Filter out non-folders
.collect())
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5589 次 |
| 最近记录: |