Search code examples
cglib

Extracting all values from a GLib GTree


I've built a GLib GTree which contains key/value pairs where the key is a character (e.g. 'a') and the value is the frequency by which that character appears in a string. For example, if the string was 'aaa' then the only element in the tree would be: 'a' => 3.

What I want to do is iterate over the tree and keep a count of the number of characters with a given frequency, i.e. where the value of the key/value pair matches.

The pseudocode would be something like:

frequency_count = 0
while (current_element = get_next_element)
  if (current_element->value == desired_frequency)
    frequency_count = frequency_count + 1

Is there a way to do this with a GTree? The only function I can find is g_tree_foreach(), but that requires me to pass a callback function that returns TRUE to stop traversing the tree, and I don't want to stop traversal until I've visited every element. Am I supposed to use the gpointer user_data parameter of the callback function to pass in the frequency count and desired frequency values?


Solution

  • Am I supposed to use the gpointer user_data parameter of the callback function to pass in the frequency count and desired frequency values?

    Yes.

    Example:

    typedef struct
    {
      guint desired_frequency;
      guint n_matches;
    } MatchData;
    
    static gboolean
    n_nodes_matching_frequency_cb (gpointer key,
                                   gpointer value,
                                   gpointer user_data)
    {
      MyTreeElement *element = value;
      MatchData *data = user_data;
    
      if (element->value == data->desired_frequency)
        data->n_matches++;
    
      return FALSE;
    }
    
    guint
    n_nodes_matching_frequency (GTree *tree,
                                guint  desired_frequency)
    {
      MatchData data = { desired_frequency, 0 };
      g_tree_foreach (tree, n_nodes_matching_frequency_cb, &data);
      return data.n_matches; 
    }