#Converting generic Vec of tuples into a generic HashMap

23 messages · Page 1 of 1 (latest)

fair hazel
#

Hello friends!

I'm trying to accomplish Vec<(T, U)> -> HashMap<T, U>.
How would I go about doing this?

What I have so far:

impl<T, U> Paginatable<T, U> for std::vec::Vec<T>
where T: Eq + std::hash::Hash + std::clone::Clone,
U: Eq + std::clone::Clone,
std::collections::HashMap<T, U>: std::convert::From<std::vec::IntoIter<T>>
{
    fn paginate(&mut self, page: u32) -> Paginator<T, U> {
        let per_page : f32 = 25.0;
        let len = self.len() as f32;
        let last_page : u32 = (len/per_page).ceil() as u32;  

        let prev_page : Option<u32>;
        let next_page : Option<u32>;

        if page != 1 {
            prev_page = Some(page - 1);
        }
        else {
            prev_page = None;
        }

        if page != last_page {
            next_page = Some(page + 1);
        }
        else {
            next_page = None;
        }

        let end : usize = (per_page as u32 * page) as usize;
        let start : usize = end - (per_page as usize);

        let values_as_hm_2 = HashMap::from(self.clone().into_iter());

        let values = into_range(values_as_hm_2, start, end);

        Paginator {
            curr_page: page,
            next_page: next_page,
            prev_page: prev_page,
            data: values,
            per_page: per_page as u32,
            last_page: last_page,
            total_hits: len as u32
        }
    }
}

The problem with this method is that when I try to call it, for instance on a Vector of tuples &str, &str, I get error regarding not satisfying trait bounds.
Of course I know what the issue is, I just want to know if there is another approach I could take to this to make it work?

main bison
#

Assuming T has an Eq + Hash bound, the easiest way to convert is vec.into_iter().collect::<HashMap<_, _>>()

fair hazel
#

Then I get errors regarding trait bounds, if I remove std::collections::HashMap<T, U>: std::convert::From<std::vec::IntoIter<T>>

main bison
#

That bound is trivially false

#

As in, you're allowed to write a function using it, but it's a lie, so you can't call that function

fair hazel
#

Yeah I know that it is, the problem is that I've kind of just been trying what the compiler is throwing at me

main bison
#

Don't try to use From or Into. The easiest way to convert between collection types is to collect an iterator.

fair hazel
#

Yeah but when I do without the trait bound, I get this:
a value of type std::collections::HashMap<_, _> cannot be built from an iterator over elements of type T

value of type std::collections::HashMap<_, _> cannot be built from std::iter::Iterator<Item=T>

help: the trait std::iter::FromIterator<T> is not implemented for std::collections::HashMap<_, _>

main bison
#

That's because your iterator isn't an iterator of tuples, it's an iterator of single elements.

#

You need an Iterator<Item = (K, V)>

#

Is your vector not a vector of tuples?

fair hazel
#

This is the call:

let res = vec![
                ("test", "testtest"),
                ("test2", "testtest"),
                ("test3", "testtest"),
                ("test4", "testtest"),
                ("test5", "testtest"),
                ("test6", "testtest"),
                ("test7", "testtest"),
                ("test8", "testtest"),
                ("test9", "testtest"),
                ("test10", "testtest"),
                ("test11", "testtest"),
                ("test12", "testtest"),
                ("test13", "testtest"),
                ("test14", "testtest"),
                ("test15", "testtest"),
                ("test16", "testtest"),
                ("test17", "testtest"),
                ("test18", "testtest"),
                ("test19", "testtest"),
                ("test20", "testtest"),
                ("test21", "testtest"),
                ("test22", "testtest"),
                ("test23", "testtest"),
                ("test24", "testtest"),
                ("test25", "testtest"),
                ("test26", "testtest"),
                ("test27", "testtest"),
                ("test28", "testtest"),
                ("test29", "testtest"),
                ("test30", "testtest"),
                ("test31", "testtest"),
                ("test32", "testtest"),
                ("test33", "testtest"),
                ("test34", "testtest"),
            ];

            let paginated = res.paginate(1);
main bison
#

The call isn't relevant.

#

The way generics work, an error inside a function isn't caused by a call external to it. It can only be caused by something local to the function

fair hazel
#

No I just wanted to show you the call, so that you have all the relevant information about what I'm trying to accomplish 😛

main bison
#

Taking a look, I think it's because your vector is self, which is defined as impl<T, U> Paginatable<T, U> for Vec<T>. Note that it's not a vector of tuples.

#

You may want to impl for Vec<(T, U)> I guess?

fair hazel
#

Oh yeah good catch

#

😮

#

That did it

#

Thank you so much @main bison 😄

#

(hoping there are no runtime errors now)

#

Can I close the issue somehow or does the server handle that by itself?