# \[Solved\] Summing a vector of refs

**URL:** <https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169>\
**Category:** help\
**Created:** [December 1, 2020, 6:01pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169 "2020-12-01T18:01:32Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![mikepurvis](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/mikepurvis/32/18232_2.png) [@mikepurvis](https://users.rust-lang.org/u/mikepurvis)\
**Post date:** [December 1, 2020, 6:01pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169/1 "2020-12-01T18:01:32Z")

</div>

This is a very novice question, as I'm just trying to learn Rust by doing this year's Advent of Code in it. I'm attempting to sum up the `Vec<&u32>` that's coming back from an itertools operation, and if I do what I think should work, I get an error:

```rust
let sum: u32 = combination.iter().sum(); // the trait `Sum<&&u32>` is not implemented for `u32`

```

In order to get around this, I seemingly have to use an `into_iter` instead, but then the `sum` takes ownership, so if I want to use the vector later, I have to clone it, which seems super gross and unnecessary:

```rust
let sum: u32 = combination.clone().into_iter().sum(); // yuck

```

Alternatively, I can just dump `sum` and fold this together myself, managing the dereference with `&val`:

```rust
let sum = combination.iter().fold(0, |sum, &val| sum + val);

```

But surely there is a way to make this work conveniently with the supplied method? Thanks!

---

<div class="post-metadata">

**Author:** ![mbrubeck](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/mbrubeck/32/648_2.png) [@mbrubeck](https://users.rust-lang.org/u/mbrubeck)\
**Post date:** [December 1, 2020, 6:08pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169/2 "2020-12-01T18:08:24Z")

</div>

> [@mikepurvis](#):
>
> `combination.iter().sum()`

You can use `combination.iter().copied().sum()` to copy the individual references in the Vec, without cloning the Vec itself.

---

<div class="post-metadata">

**Author:** ![eko](https://avatars.discourse-cdn.com/v4/letter/e/a8b319/32.png) [@eko](https://users.rust-lang.org/u/eko)\
**Post date:** [December 1, 2020, 6:20pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169/3 "2020-12-01T18:20:08Z")

</div>

You can also look at this question for understanding why `combination.iter()` yields `&&u32`s:

> [@Understanding Rust functional programming styles](https://users.rust-lang.org/t/understanding-rust-functional-programming-styles/52110):
>
> I'm a very beginner to Rust and I got confused by Rust functional programming style code. Assume freq is a vector containing non negative integers. The below code makes me confused. Get the largest index with a positive value. let key\_max = (0..denom).rev().step\_by(1).filter(|&i| freq[i] \> 0).next().unwrap(); Get the number of positive values in freq. let size = freq.iter().filter(|&&f| f \> 0u32).count(); I wonder why the first line of code use &i (a single &) while the second line of cod…

---

<div class="post-metadata">

**Author:** ![mikepurvis](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/mikepurvis/32/18232_2.png) [@mikepurvis](https://users.rust-lang.org/u/mikepurvis)\
**Post date:** [December 1, 2020, 6:25pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169/4 "2020-12-01T18:25:54Z")

</div>

Thanks! I actually had found that discussion and I understand the logic of why the generic iterator works this way. My question is more about what the accepted, idiomatic way is to do this type of operation. The recommendation from @mbrubeck seems reasonable, and [the documentation](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.copied) is fairly explicit about it existing to solve this exact problem:

> Creates an iterator which copies all of its elements.
> 
> This is useful when you have an iterator over `&T` , but you need an iterator over `T` .

On the other hand, in a case where those copies had an actual cost, I suppose you'd just do the `fold` manually? Is there something technical (or philosophical) which prevents `std::iter::Sum` from accepting `&&` types?

---

<div class="post-metadata">

**Author:** ![H2CO3](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@H2CO3](https://users.rust-lang.org/u/H2CO3)\
**Post date:** [December 1, 2020, 6:42pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169/5 "2020-12-01T18:42:04Z")

</div>

What do you mean "actual cost"? A `Copy` is exactly a bitwise memcopy, nothing more, nothing less. It's never completely free, but in the overwhelming majority of cases (i.e. for small value types), it's _almost_ free.

Writing out the loop manually doesn't make the operation any faster – there's no way around moving primitives into CPU registers from the heap in order to perform an `add` instruction on them.

---

<div class="post-metadata">

**Author:** ![mbrubeck](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/mbrubeck/32/648_2.png) [@mbrubeck](https://users.rust-lang.org/u/mbrubeck)\
**Post date:** [December 1, 2020, 6:43pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169/6 "2020-12-01T18:43:36Z")

</div>

> [@mikepurvis](#):
>
> On the other hand, in a case where those copies had an actual cost, I suppose you'd just do the `fold` manually?

Your manual `fold` is also making a copy, by using the pattern `&val` to destructure the reference and copy its referent into `val`.

`iter.copied()` can also be written as `iter.map(|&val| val)`.

---

<div class="post-metadata">

**Author:** ![mikepurvis](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/mikepurvis/32/18232_2.png) [@mikepurvis](https://users.rust-lang.org/u/mikepurvis)\
**Post date:** [December 1, 2020, 7:04pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169/7 "2020-12-01T19:04:50Z")

</div>

Got it, that makes sense! I think in my mind a dereference is somehow free, but yeah it makes sense that the value has to be copied onto the stack one way or another. Here's what my final solution was (to [this puzzle](https://adventofcode.com/2020/day/1)):

```rust
    for num in 2..4 {
        for combination in numbers.iter().combinations(num) {
            let sum: u32 = combination.iter().copied().sum();
            if sum == 2020 {
                let product: u32 = combination.iter().copied().product();
                println!("{}", product);
                break;
            }
        }
    }

```

@H2CO3 The situation I'm thinking of would be something like where it's a series of large objects that you have a vector of refs to, and you want to do something with a singular field on those objects— maybe sum up all the values in that particular field, but without incurring the cost of copying all the containing objects. Anyway, it's a contrived example since in that case you're into custom logic anyway, but that's the idea anyway.

---

<div class="post-metadata">

**Author:** ![H2CO3](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@H2CO3](https://users.rust-lang.org/u/H2CO3)\
**Post date:** [December 1, 2020, 8:37pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169/8 "2020-12-01T20:37:56Z")

</div>

In that case, you can still use `.map()` instead of writing out an explicit loop:

```rust
#[derive(Debug, Clone)] // it's not even `Copy`
struct Huge {
    do_not_copy_me: [u64; 10_000],
    i_am_cheap: u64,
}

fn main() {
    let huger = vec![Huge {
        do_not_copy_me: [42; 10_000],
        i_am_cheap: 1337,
    }; 100];

    let sum: u64 = huger.iter().map(|x| x.i_am_cheap).sum();
    println!("sum = {}", sum);
}

```

---

<div class="post-metadata">

**Author:** ![mikepurvis](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/mikepurvis/32/18232_2.png) [@mikepurvis](https://users.rust-lang.org/u/mikepurvis)\
**Post date:** [December 1, 2020, 9:13pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169/9 "2020-12-01T21:13:04Z")

</div>

Just chiming in here again to say that I think I understand this much better after [this reddit post](https://www.reddit.com/r/rust/comments/k4hoyk/advent_of_code_2020_day_1/geap4iv) explained it from another angle.

Basically, it's not `Vec<&T>` that's the problem— the sum trait actually supports ref values. The issue is `Vec<&&T>`, and that is happening because there are _two_ iterators in play. There's the first iterator which feeds the `combinations` call, and then the second iterator to perform the `sum`/`product` operations. I found it much clearer to move the `copied` call up to the first iterator, so that the combinations I'm operating on are vectors of integers rather than vectors of refs to integers. So the final version is then:

```rust
    for num in 2..4 {
        for combination in numbers.iter().copied().combinations(num) {
            let sum: u32 = combination.iter().sum();
            if sum == 2020 {
                let product: u32 = combination.iter().product();
                println!("{}", product);
                break;
            }
        }
    }

```

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [March 1, 2021, 9:13pm UTC](https://users.rust-lang.org/t/solved-summing-a-vector-of-refs/52169/10 "2021-03-01T21:13:07Z")

</div>

Closed on March 1, 2021, 9:13pm UTC

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
