如何将其他元素推向Vec<& vec< gt;>?

发布于 2025-02-11 22:36:29 字数 670 浏览 1 评论 0 原文

我正在尝试完成一些简单的事情,但不确定如何在Rust中做到这一点。

我有一个vec<& vec>,类似于以下示例。

[
 ["a1", "b2", "c3"],
 ["d1", "e2", "f3"],
 ["g1", "h2", "i3"]
]

我想在每个向量的末尾推一个字符串。

[
 ["a1", "b2", "c3", "something"],
 ["d1", "e2", "f3", "something"],
 ["g1", "h2", "i3", "something"]
]

到目前为止,我尝试过的是:

vec_of_strings
    .iter_mut()
    .map(|x| x.clone().push("something".to_string()))
    .collect::<Vec<_>>();

println!("{:?}", vec_of_strings);

但是输出表明什么都没有附加。

I am trying to accomplish something rather simple, but not sure how to do it in Rust.

I have a Vec<&Vec>, something like the below example.

[
 ["a1", "b2", "c3"],
 ["d1", "e2", "f3"],
 ["g1", "h2", "i3"]
]

I want to push an additional string at the end of each vector.

[
 ["a1", "b2", "c3", "something"],
 ["d1", "e2", "f3", "something"],
 ["g1", "h2", "i3", "something"]
]

What I've tried so far is below:

vec_of_strings
    .iter_mut()
    .map(|x| x.clone().push("something".to_string()))
    .collect::<Vec<_>>();

println!("{:?}", vec_of_strings);

But the output is showing that nothing is appended.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

战皆罪 2025-02-18 22:36:29

您正在做的是创建新的 vec ,它不会修改存在的。实际上,当您不成熟时,现有的商品无法修改(&amp; in vec&lt;&amp;&amp;&amp; vec&lt; _ _&gt;&gt; )。

请注意,使用 .iter_mut()而不是 .Iter()在这里毫无意义,因为您没有突变元素。

此外, vec :: push()不返回任何内容,因此 .to_string() Invocation应该给您编译时错误。 (我假设您是要在字符串文字上调用它。)

解决上述问题:

let new_vec_of_strings = vec_of_strings
  .iter()
  .map(|x| {
    let mut x = x.clone();
    x.push("something".to_string());
    x
  })
  .collect::<Vec<_>>();

println!("{:?}", new_vec_of_strings);

但是,这一切似乎都像 xy问题< /a> - 可能有一种更好的方法来实现您的目标。

What you're doing creates a new Vec, it does not modify the exist ones. Indeed, the existing ones cannot be modified as you are borrowing them immutably (the & in Vec<&Vec<_>>).

Note that using .iter_mut() instead of .iter() is pointless here as you aren't mutating the elements.

Additionally, Vec::push() doesn't return anything, so the .to_string() invocation should be giving you a compile-time error. (I assume you meant to call this on the string literal instead.)

Fixing the above issues:

let new_vec_of_strings = vec_of_strings
  .iter()
  .map(|x| {
    let mut x = x.clone();
    x.push("something".to_string());
    x
  })
  .collect::<Vec<_>>();

println!("{:?}", new_vec_of_strings);

However, this all seems like an XY problem -- there is probably a better way to accomplish whatever your goal is.

甜点 2025-02-18 22:36:29

如果我正确理解,则需要在 MAP 中返回 vec

fn main() {
    let mut vec_of_strings = vec![
        vec!["a1", "b2", "c3"], 
        vec!["d1", "e2", "f3"], 
        vec!["g1", "h2", "i3"]
    ];
    println!("{:?}", vec_of_strings);
    
    let vec_of_strings: Vec<Vec<&str>> = vec_of_strings.iter_mut().map(|x| {x.push("something"); x.clone()}).collect();
    println!("{:?}", vec_of_strings);
}

If I understand correctly, You need to return a vec in map.

fn main() {
    let mut vec_of_strings = vec![
        vec!["a1", "b2", "c3"], 
        vec!["d1", "e2", "f3"], 
        vec!["g1", "h2", "i3"]
    ];
    println!("{:?}", vec_of_strings);
    
    let vec_of_strings: Vec<Vec<&str>> = vec_of_strings.iter_mut().map(|x| {x.push("something"); x.clone()}).collect();
    println!("{:?}", vec_of_strings);
}

Rust Playground

拥抱影子 2025-02-18 22:36:29

我认为对地图方法的方法有误解。该方法通常用于原始值保持不变的数据转换。您在这里真正做的是造成副作用, MAP 方法在这里根本没有帮助您。

只需使用循环的即可。这并不是说您使用地图和插入器保存击键。

但是,您提到您有一个 vec&lt;&amp; vec&gt; 。拥有这种类型似乎不适合您的目的。克隆整个vec只是为了添加1个元素,对于性能是可怕的。

我看到了2个选择:要么拥有完全拥有,即 vec&lt; vec&gt; ,要么只是使Inner vec sable可变,如 vec&amp; mut中vec&gt;

这是第一个选项,我认为这是最惯用的:

fn main() {
    let mut vec_of_strings = vec![
        vec!["a1", "b2", "c3"], 
        vec!["d1", "e2", "f3"], 
        vec!["g1", "h2", "i3"]
    ];
 
    for vec in vec_of_strings.iter_mut() {
        vec.push("something");
    }
    
    println!("{vec_of_strings:?}");
}

如果以拥有形式的形式不可接受,那么另一种选择是使用 vec&&amp&amp; mut vec vec&gt;

fn main() {
    fn main() {
    let mut vec_of_strings = vec![
        vec!["a1", "b2", "c3"], 
        vec!["d1", "e2", "f3"], 
        vec!["g1", "h2", "i3"]
    ];
    
    //suppose somehow a function gave you this:
    let vec_of_mut_strings: Vec<&mut Vec<_>> = vec_of_strings
        .iter_mut()
        .collect();
    
    for vec in vec_of_mut_strings {
        vec.push("something");
    }
    
    //notice that the original vec_of_strings change
    println!("{vec_of_strings:?}");
}
}

I think there's a misunderstanding on what the map method was made for. This methodis generally used for data transformations where the original values remain unchanged. What you are really doing here is causing a side effect, and the map method does not help you at all here.

Just use a for loop. It's not like you're saving keystrokes by using map and interators.

However, you mentioned you have a Vec<&Vec>. Having this type seems unfit for your purpose. Cloning the entire vec just to add 1 element is terrible for performance.

I see 2 choices: either have it fully owned, i.e. Vec<Vec>, or just make the inner Vecs mutable, as in Vec<&mut Vec>.

This is the first option, and I think this is the most idiomatic:

fn main() {
    let mut vec_of_strings = vec![
        vec!["a1", "b2", "c3"], 
        vec!["d1", "e2", "f3"], 
        vec!["g1", "h2", "i3"]
    ];
 
    for vec in vec_of_strings.iter_mut() {
        vec.push("something");
    }
    
    println!("{vec_of_strings:?}");
}

If having it in an owned form is not acceptable, then another option is to use Vec<&mut Vec>:

fn main() {
    fn main() {
    let mut vec_of_strings = vec![
        vec!["a1", "b2", "c3"], 
        vec!["d1", "e2", "f3"], 
        vec!["g1", "h2", "i3"]
    ];
    
    //suppose somehow a function gave you this:
    let vec_of_mut_strings: Vec<&mut Vec<_>> = vec_of_strings
        .iter_mut()
        .collect();
    
    for vec in vec_of_mut_strings {
        vec.push("something");
    }
    
    //notice that the original vec_of_strings change
    println!("{vec_of_strings:?}");
}
}
¢蛋碎的人ぎ生 2025-02-18 22:36:29

我假设您的输出看起来像这样:

[(), (), ()]

以下是一些建议:

  • 更喜欢使用 for_each 用于突变而不是地图

      vec_o​​f_strings
        .ITER_MUT()
        .for_each(| x | {
            X.Push(“某物”);
        });
    
    println!(“ {:?}”,vec_o​​f_strings);
     

    请注意,这是假定 vec_o​​f_strings 的定义类似:

     让mut vec1 = vec![“ a1”,“ b2”,“ c3”];
    令mut vec2 = vec![“ d1”,“ e2”,“ f3”];
    令mut vec3 = vec![“ g1”,“ h2”,“ i3”];
    令mut vec_o​​f_strings:vec&lt;&amp; mut vec&lt; = vec![&amp; mut Vec1,&amp; mut Vec2,&amp; mut Vec3];
     


  • Playgroung 't返回任何东西,因为 vec :: push 不返回向量。

    独立 x 到另一行以返回向量。

      vec_o​​f_strings.iter_mut()
        .map(| x | {
            X.Push(“某物”);
            x
        }))
        。
     

    请注意,这是假定 vec_o​​f_strings 的定义类似:

     让mut vec1 = vec![“ a1”,“ b2”,“ c3”];
    令mut vec2 = vec![“ d1”,“ e2”,“ f3”];
    令mut vec3 = vec![“ g1”,“ h2”,“ i3”];
    令mut vec_o​​f_strings:vec&lt;&amp; mut vec&lt; = vec![&amp; mut Vec1,&amp; mut Vec2,&amp; mut Vec3];
     


  • 您在使用矢量元素的类型(&amp; str )时可能更明确>地图:

      .collect ::&lt; vec&lt;&amp;&amp; str&gt;&gt;();
     

    而不是

      .collect ::&lt; vec&lt; _&gt;&gt;();
     

    是由编译器推断为 vec&lt;()&gt; ,因为 vec的返回类型因此,输出)。


I assume your output looks like this:

[(), (), ()]

Here are some suggestions:

  • Prefer using for_each for mutations instead of map:

    vec_of_strings
        .iter_mut()
        .for_each(|x| {
            x.push("something");
        });
    
    println!("{:?}", vec_of_strings);
    

    Note that this assumes that the vec_of_strings is defined similarly as such:

    let mut vec1 = vec!["a1", "b2", "c3"];
    let mut vec2 = vec!["d1", "e2", "f3"];
    let mut vec3 = vec!["g1", "h2", "i3"];
    let mut vec_of_strings: Vec<&mut Vec<&str>> = vec![&mut vec1, &mut vec2, &mut vec3];
    

    Playground

  • The function in .map in your example doesn't return anything because Vec::push doesn't return the vector.

    Separate x to another line to return the vector.

    vec_of_strings.iter_mut()
        .map(|x| {
            x.push("something");
            x
        })
        .collect::<Vec<&str>>();
    

    Note that this assumes that the vec_of_strings is defined similarly as such:

    let mut vec1 = vec!["a1", "b2", "c3"];
    let mut vec2 = vec!["d1", "e2", "f3"];
    let mut vec3 = vec!["g1", "h2", "i3"];
    let mut vec_of_strings: Vec<&mut Vec<&str>> = vec![&mut vec1, &mut vec2, &mut vec3];
    

    Playground

  • You might also like to be more explicit with the type of the vector elements (&str) when using map:

        .collect::<Vec<&str>>();
    

    instead of

        .collect::<Vec<_>>();
    

    which was inferred as Vec<()> by the compiler because of the return type of Vec::push in map (hence the output).

初与友歌 2025-02-18 22:36:29

一种解决原始格式将每个数组延伸到一个条目的解决方案:

vec_of_strings
    .iter_mut()
    .map(|a| {
        let mut v = a.to_vec();
        v.push("something");
        let arr: [&str; 4] = v.try_into().unwrap();
        arr
    })
    .collect::<Vec<[&str; 4]>>();

游乐场

A solution that keeps the original format extending each array by one entry:

vec_of_strings
    .iter_mut()
    .map(|a| {
        let mut v = a.to_vec();
        v.push("something");
        let arr: [&str; 4] = v.try_into().unwrap();
        arr
    })
    .collect::<Vec<[&str; 4]>>();

Playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文