I want to filter a HashMap value to a vector

Hello!

I want to filter a HashMap value to a vector, but I can't solve the error.
I would like to know how to convert it to vector successfully. Thank you in advance.

[Error]

$ cargo build
Compiling
error[E0277]: a value of type `std::vec::Vec<std::string::String>` cannot be built from an iterator over elements of type `&std::string::String`
    --> src/encrypted_notes_backend/src/devices_store.rs:123:17
     |
123  | /                 user_aliases
124  | |                     .values()
125  | |                     .filter(|value| !user_keys.contains_key(*value))
126  | |                     .clone()
     | |____________________________^ value of type `std::vec::Vec<std::string::String>` cannot be built from `std::iter::Iterator<Item=&std::string::String>`
127  |                       .collect::<Vec<PublicKey>>()
     |                        ------- required by a bound introduced by this call
     |
     = help: the trait `FromIterator<&std::string::String>` is not implemented for `std::vec::Vec<std::string::String>`
     = help: the trait `FromIterator<T>` is implemented for `std::vec::Vec<T>`
note: required by a bound in `collect`
    --> /Users/yukasaito/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:1832:19
     |
1832 |     fn collect<B: FromIterator<Self::Item>>(self) -> B
     |                   ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `encrypted_notes_backend` due to previous error
warning: build failed, waiting for other jobs to finish...
error: could not compile `encrypted_notes_backend` due to previous error

[Code]

pub type Address = String;
pub type EncryptedSecret = String;
pub type DeviceAlias = String;
pub type PublicKey = String;

pub struct DevicesStore {
    pub aliases: HashMap<Address, HashMap<DeviceAlias, PublicKey>>,
    pub keys: HashMap<Address, HashMap<PublicKey, EncryptedSecret>>,
}

impl DevicesStore {
    pub fn get_unsynced_publickeys(&self, caller: Address) -> Vec<PublicKey> {
        let user_keys = self.keys.get(&caller).expect("ERROR");

        match self.aliases.get(&caller) {
            Some(user_aliases) => {
                user_aliases
                    .values()
                    .filter(|value| !user_keys.contains_key(*value))
                    .clone()
                    .collect::<Vec<PublicKey>>()
            }
            None => {
                vec![]
            }
        }
    }
}

You want .cloned(), not .clone(). The former is a proper iterator adaptor that returns a transforming iterator which turns references into cloned values; the latter (what you currently have) is just a regular call to clone, which knows nothing about iterators, and merely clones the value it is being called on (in your case, the iterator itself).

1 Like

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.