admin管理员组

文章数量:1362779

I have src: Vec<Foo> and dst: &mut [Foo]. I want to move as many elements as possible from src into dst. Specifically:

  • If src is shorter than dst, then the beginning of dst should be replaced with what was in src (leaving the rest of dst as-is), and src should end up empty.
  • If src and dst are the same length, all of the values in dst should be replaced with what was in src, and src should end up empty.
  • If src is longer than dst, all of the values in dst should be replaced with what was in the beginning of src, and src should be left with only the elements that didn't fit.

For example, pretending Foo was i32 (but it should work for non-Copy types too):

  • If src starts as [1,2] and dst starts as [7,8,9,10], src should end up as [] and dst should end up as [1,2,9,10].
  • If src starts as [1,2,3,4] and dst starts as [7,8,9,10], src should end up as [] and dst should end up as [1,2,3,4].
  • If src starts as [1,2,3,4,5,6] and dst starts as [7,8,9,10], src should end up as [5,6] and dst should end up as [1,2,3,4].

I know I could loop manually and move one element at a time, but it seems like there should be a Drain-like approach instead.

I have src: Vec<Foo> and dst: &mut [Foo]. I want to move as many elements as possible from src into dst. Specifically:

  • If src is shorter than dst, then the beginning of dst should be replaced with what was in src (leaving the rest of dst as-is), and src should end up empty.
  • If src and dst are the same length, all of the values in dst should be replaced with what was in src, and src should end up empty.
  • If src is longer than dst, all of the values in dst should be replaced with what was in the beginning of src, and src should be left with only the elements that didn't fit.

For example, pretending Foo was i32 (but it should work for non-Copy types too):

  • If src starts as [1,2] and dst starts as [7,8,9,10], src should end up as [] and dst should end up as [1,2,9,10].
  • If src starts as [1,2,3,4] and dst starts as [7,8,9,10], src should end up as [] and dst should end up as [1,2,3,4].
  • If src starts as [1,2,3,4,5,6] and dst starts as [7,8,9,10], src should end up as [5,6] and dst should end up as [1,2,3,4].

I know I could loop manually and move one element at a time, but it seems like there should be a Drain-like approach instead.

Share Improve this question asked 2 days ago Joseph Sible-Reinstate MonicaJoseph Sible-Reinstate Monica 48.7k7 gold badges54 silver badges109 bronze badges 3
  • Why can't you use Vec::drain? It seems unlikely something more specific is available. – cafce25 Commented 2 days ago
  • @cafce25 I can do that; the piece I was missing was just zip, so what I thought I'd have to do was more complicated than necessary. I'm going to give cdhowie's answer a try now, since it looks like exactly what I need. – Joseph Sible-Reinstate Monica Commented 2 days ago
  • Note that it will be more efficient if in the 3rd case you can instead take the elements from the end of src. – Chayim Friedman Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 4

This is easy to do just by figuring out how many elements you can move (which is the minimum of both lengths) and then using drain to remove those elements and place them in the destination.

pub fn move_many<T>(src: &mut Vec<T>, dst: &mut [T]) {
    let count = src.len().min(dst.len());

    for (s, d) in src.drain(0..count).zip(dst) {
        *d = s;
    }
}

(Playground)

本文标签: rustHow do I move as many elements as possible from a Vec into a preexisting sliceStack Overflow