1

I have a string from a CSV file that contains multiple lines:

Edit. Rust was not in the actual string.

header1,header2,header3
r1v1,r1v2,r1v3
r2v1,r2v2,r2v3

I am trying to push these into a Vec<Vec<String>>:

// the csv is raw_string
let lines = raw_string.lines();
let mut mainVec = Vec::new();

for row in lines {
    let mut childVec = Vec::new();
    let trimmed = row.trim();
    let values = trimmed.split(',').collect();
    childVec.push(values);
    mainVec.push(childVec.clone());
}

But I get the error

error[E0282]: unable to infer enough type information about `_`
 --> src/main.rs:9:13
  |
9 |         let values = trimmed.split(',').collect();
  |             ^^^^^^ cannot infer type for `_`
  |
  = note: type annotations or generic parameter binding required
5
  • You really want a Vec<Vec<Vec<&str>>>? o_O Commented Mar 16, 2017 at 4:30
  • @ildjarn Since the OP is "trying to push to a Vec<Vec<String>>", it seems they want a Vec<Vec<String>> (two Vecs, not three). Commented Mar 16, 2017 at 9:53
  • @user4815162342 : Ah, somehow I'd missed that bit. That said, getting rid of childVec should be part of the answer then. Commented Mar 16, 2017 at 9:56
  • @ildjarn No, you are completely right, sorry about that. The OP really does want a Vec<Vec<String>>, but their code is creating a Vec<Vec<Vec<String>>> with an unnecessary one-element vector in the middle. Commented Mar 16, 2017 at 13:06
  • 1
    The true answer is to use the csv crate because parsing CSV is harder than everyone thinks it is. Commented Mar 16, 2017 at 14:10

2 Answers 2

5

Another solution, based on iterators:

fn main() {
    let raw_string = r"rust
header1,header2,header3
r1v1,r1v2,r1v3
r2v1,r2v2,r2v3";

    let main_vec = raw_string.lines()
                             .map(|s| s.trim().split(',').map(String::from).collect::<Vec<String>>())
                             .collect::<Vec<Vec<String>>>();

    print!("{:?}", main_vec);
}

As @Simon Whitehead has already said, the the only thing you need to do with collect() is to specify the type because this is a generic method. But it may also be deduced by the compiler itself in some circumstances.

The code above is pretty verbose about type specification: actually you may leave the Vec's value type unspecified and let it be deduced by the compiler like this:

let main_vec = raw_string.lines()
                         .map(|s| s.trim().split(',').map(String::from).collect::<Vec<_>>())
                         .collect::<Vec<_>>();

For more information, see the definition of collect() method.

Sign up to request clarification or add additional context in comments.

3 Comments

OP wants a Vec<Vec<String>> rather than a Vec<Vec<&str>> so after the split there should be a .map(String::from) or somesuch.
@ildjarn True that seems to be my problem, I can't figure out the right spot to drop in either the String::from() or the .to_string() methods.
@mjwrazor : What Victor has at the end, plus a .map(String::from) after the split: .map(|s| s.trim().split(',').map(String::from).collect::<Vec<_>>()). (Other options are available e.g. .map(|s| s.trim().split(',').map(ToString::to_string).collect::<Vec<_>>()), but I think using From reads best.)
3

You need to give the compiler a little hint as to what you want values to be.

You can say you want it to be a vector of something:

let values: Vec<_> = trimmed.split(',').collect();

Working example in the playground

A few other notes about the code, if you're interested.

  • The variable names should be snake_case. So the vectors should be called main_vec and child_vec.
  • The child_vec does not need to be cloned when pushing it to the main_vec. Pushing it to main_vec transfers ownership and the loop redeclares the child_vec and so the compiler can guarantee nothing has been violated here.

1 Comment

This solution also works. gist

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.