简体   繁体   中英

Rust - How to add data to a triply nested HashMap

I am trying to split up a bunch (50+) of json files, and to do so I want to classify their values by frequency depending on elements of the file name. Not only am I doing this but I am doing it as somewhat of a Rust newbie, because it wasn't fun enough to do in Python, for instance.

For the sake of the explanation, let's imagine files like these:

a-b-c-d.json
{
    "var":"foo",
    "array": [
        'one',
        'two'
    ]
}
b-c-d-f.json
{
    "var":"bar",
    "array": [
        'one',
        'three'
    ]
}

The data structure I want to end up with, after processing those two files, is something like this (note that this might very well be my first mistake):

{
  'a' : {
    'var' : { 
      'foo': 1
    }, 'array' : {
      'one': 1, 'two': 1 
    }
  },
  'b' : {
    'var' : { 
      'foo': 1,
      'bar': 1
    }, 'array' : {
      'one': 2, 'two': 1, 'three': 1
    }
  }
(also 'c', 'd' and 'f') - I hope the intention is clear with this small example
}

My pseudocode is more or less like this:

  1. for each json file
  2. split the name in parts, by '-'
  3. for each element (key:value) in the json file
  4. add it to result[part][key][value] as the number of occurrences

So, the type of the result variable would be HashMap<String, HashMap<String, HashMap<String, i8>>>

And the (actual) code in which I am getting errors is:

type ComponentValueElement = HashMap<String, i8>;
type ComponentElement = HashMap<String, ComponentValueElement>;
type ComponentMap = HashMap<String, ComponentElement>;
(...)
fn increase_ocurrence_of_element_in_configuration(component: &String, element: &String, value: &String, final_component_map: &mut ComponentMap) {
    final_component_map.entry(component.into()).or_insert( HashMap::new() );
    final_component_map[component].entry(element.into()).or_insert(HashMap::new());
    final_component_map[component][element].entry(value.into()).or_insert(0);

    final_component_map[component][element][value] += 1;
}

The errors are:

<final_component_map[component]>.entry(element.into()).or_insert(HashMap::new());

cannot borrow data in an index of `std::collections::HashMap<std::string::String, std::collections::HashMap<std::string::String, std::collections::HashMap<std::string::String, i8>>>` as mutable

cannot borrow as mutable

help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<std::string::String, std::collections::HashMap<std::string::String, std::collections::HashMap<std::string::String, i8>>>`

<final_component_map[component][element]>.entry(value.into()).or_insert(0);

cannot borrow data in an index of `std::collections::HashMap<std::string::String, std::collections::HashMap<std::string::String, i8>>` as mutable

cannot borrow as mutable

help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<std::string::String, std::collections::HashMap<std::string::String, i8>>`

<final_component_map[component][element][value]> += 1;

cannot assign to data in an index of `std::collections::HashMap<std::string::String, i8>`

cannot assign

help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<std::string::String, i8>`

I would have thought that writing to Maps would be easier in Rust:D What exactly do I need to do to have my beautiful nested HashMap filled with the values?

Thanks a lot!

Part of the point of the Entry API is so that you can mutate the entry without having to look it up again. You can chain these lookups together like so:

fn increase_ocurrence_of_element_in_configuration(
    component: &str,
    element: &str,
    value: &str,
    final_component_map: &mut ComponentMap,
) {
    *final_component_map
        .entry(component.into())
        .or_default()
        .entry(element.into())
        .or_default()
        .entry(value.into())
        .or_default() += 1;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM