How to convert from Iterator to Vector?


#1

My task: get all filenames and sosrting it’s fiels

My source code:

extern crate csv;

use std::fs;
use std::string::String;



fn main() {
    let paths: Vec<_> = fs::read_dir("test_data").unwrap().cloned().collect().sort();
}

Errors:

   Compiling moex_analytic_rust v0.0.1 (file:///home/dmitry/web/moex_analytic_rust)
src/main.rs:9:60: 9:68 error: type mismatch resolving `<std::fs::ReadDir as core::iter::Iterator>::Item == &_`:
 expected enum `core::result::Result`,
    found &-ptr [E0271]
src/main.rs:9     let paths: Vec<_> = fs::read_dir("test_data").unwrap().cloned().collect().sort();
                                                                         ^~~~~~~~
src/main.rs:9:60: 9:68 help: run `rustc --explain E0271` to see a detailed explanation
src/main.rs:9:69: 9:78 error: no method named `collect` found for type `core::iter::Cloned<std::fs::ReadDir>` in the current scope
src/main.rs:9     let paths: Vec<_> = fs::read_dir("test_data").unwrap().cloned().collect().sort();
                                                                                  ^~~~~~~~~
src/main.rs:9:69: 9:78 note: the method `collect` exists but the following trait bounds were not satisfied: `core::iter::Cloned<std::fs::ReadDir> : core::iter::Iterator`
error: aborting due to 2 previous errors
Could not compile `moex_analytic_rust`.

To learn more, run the command again with --verbose.

#2

There are several issues here:

  • You need two levels of unwrap() to get paths and panic on errors - the read_dir() function returns a result (because opening the directory can fail) and each iteration’s next returns a result (because reading one entry can fail).
  • cloned() is only defined for iterators that return references. read_dir() returns owned instances of Result<DirEntry>.
  • sort() on a Vec returns not the Vec, but (). Therefore your paths would be ().
  • read_dir() yields DirEntrys, which cannot be sorted.

A working example would be

fn main() {
    let mut paths: Vec<_> = fs::read_dir("test_data").unwrap().map(|res| res.unwrap().path()).collect();
    paths.sort();
}

Once you switch to handling the errors instead of panicking, you can also collect an iterator over Results into a Result<Vec<_>> and use that together with try!.

Finally, obligatory reference to walkdir.


#3

Thank you