Top |
GList * | gx_list_filter () |
gboolean | gx_list_every () |
gboolean | gx_list_any () |
GList * | gx_list_filter_in_place () |
GList * | gx_list_take () |
GList * | gx_list_take_in_place () |
GList * | gx_list_skip () |
GList * | gx_list_skip_in_place () |
GList * | gx_list_map () |
GList * | gx_list_map_in_place () |
gpointer | gx_list_fold () |
GList * | gx_list_iota () |
gint | gx_list_sum () |
gint | gx_list_product () |
A GList is a double-linked list data structure for storing arbitrary data. GXLib offers a number of functions for GList that allow for list manipulation with a functional flavor. The functions are inspired by the list operations in Mozilla's Rust,
Scheme's SRFI-1 and their use for problems such as those from Project Euler.Suppose we want to find the sum of the prime numbers up to 100. We can use a
combination of gx_list_iota()
, gx_list_filter_in_place()
, gx_is_prime()
and
gx_list_sum()
to accomplish this. You could use a one-liner for this, but
let's do it in steps:
1 2 3 4 5 6 7 8 9 10 11 12 |
gint sum; GList *nums; // numbers 1..100 (inclusive) nums = gx_list_iota (100, 1, 1); // filter out the non-primes nums = gx_list_filter_in_place (nums, (GXPred)gx_is_prime, NULL, NULL); // take the sum sum = gx_list_sum (num); g_assert_cmpint (sum, ==, 1060); g_list_free (nums); |
GList * gx_list_filter (GList *list
,GXPred pred_func
,gpointer user_data
);
Create a GList consisting of a shallow copy of the elements of list
for
which the predicate function pred_func
returns TRUE
.
Note, for the inverse operation (removing all items for with a predicate
function returns FALSE
), see g_list_remove_all()
.
Example: getting a list of natural numbers up to 100 that can be divided by either 3 or 5
1 2 3 4 5 6 7 8 9 10 11 |
static gboolean div_3_5 (gint n) { return n % 3 == 0 || n % 5 == 0; } GList *lst, *filtered; lst = gx_list_iota (100, 1, 1); // getting a list 1..100 filtered = gx_list_filter (lst, (GXPred)div_3_5, NULL); // do something useful with filtered g_list_free (lst); g_list_free (filtered); |
list |
a GList |
|
pred_func |
a predicate function |
|
user_data |
a user pointer passed to |
[allow-none] |
gboolean gx_list_every (GList *list
,GXPred pred_func
,gpointer user_data
);
Check if the predicate is true for every element in list
. If list
is empty,
this is considered TRUE
.
Example: let's verify that not every number in [1..10] is a prime number:
1 2 3 4 5 6 |
GList *lst; lst = gx_list_iota (10, 1, 1); g_assert_false (gx_list_every (lst, (GXPred)gx_is_prime, NULL)); g_list_free (lst); |
list |
a GList |
|
pred_func |
a predicate function |
|
user_data |
a user pointer passed to |
[allow-none] |
gboolean gx_list_any (GList *list
,GXPred pred_func
,gpointer user_data
);
Check if the predicate is true for any element in list
. If list
is empty,
this is considered FALSE
.
Example: let's see if there are any prime-numbers between 20 and 30:
1 2 3 4 5 6 |
GList *lst; lst = gx_list_iota (10, 20, 1); g_assert_true (gx_list_any (lst, (GXPred)gx_is_prime, NULL)); g_list_free (lst); |
list |
a GList |
|
pred_func |
a predicate function |
|
user_data |
a user pointer passed to |
[allow-none] |
GList * gx_list_filter_in_place (GList *list
,GXPred pred_func
,gpointer user_data
,GDestroyNotify free_func
);
Remove elements from list
for which pred_func
does not return TRUE
. The
removed elements are freed with free_func
.
Note, for the inverse operation (removing all items for with a predicate
function returns TRUE
), see g_list_remove_all()
.
1 |
// Example |
list |
a GList |
|
pred_func |
a predicate function |
|
user_data |
a user pointer passed to |
[allow-none] |
free_func |
function to free elements that are filtered-out. |
[allow-none] |
GList * gx_list_take (GList *list
,gsize n
);
Take up to n
elements from list
; if n
is greater than the length of list
,
return the whole list.
Note that this uses a shallow copy of the values in list
, so the list from
which the elements were taken and the resulting list, share the data items.
1 2 3 4 5 6 7 8 9 10 |
const char* words[] = { "foo", "bar", "cuux", NULL }; GList *lst, *first2; lst = gx_strv_to_list (words, -1); first2 = gx_list_take (lst, 2); // foo, bar // do something useful with first2 g_list_free (lst); g_list_free (lst2); |
GList * gx_list_take_in_place (GList *list
,gsize n
,GDestroyNotify free_func
);
Like gx_list_take()
, but affects the list in-place; effectively, this reduces
list
to its first n
elements, or all elements if n
is greater than the
length of list
.
1 |
// Example |
list |
a GList |
|
n |
the number of elements to take |
|
free_func |
function to free the removed elements. |
[allow-none] |
GList * gx_list_skip (GList *list
,gsize n
);
Return a list of all but the first n
elements of list
. If n
is greater
than the length of list
, return the empty list.
Note that this uses a shallow copy of the values in list
, so the list from
which the elements were taken and the resulting list, share the data items.
1 |
// Example |
GList * gx_list_skip_in_place (GList *list
,gsize n
,GDestroyNotify free_func
);
Remove the first n
elements from list
. If n
is greater than the length of
list
, return the empty list.
1 |
// Example |
list |
a GList |
|
n |
the number of elements to take |
|
free_func |
function to free the removed elements. |
[allow-none] |
GList * gx_list_map (GList *list
,GXBinaryFunc map_func
,gpointer user_data
);
Create a new list of consisting of the elements obtained by applying
map_func
to the corresponding elements in list
.
1 2 3 4 5 6 7 8 9 10 |
GList *lst, *upper; const char* cities[] = { "Aruba", "Hawaii", "Zanzibar", NULL }; lst = gx_strv_to_list (cities, -1); upper = gx_list_map (lst, (GXBinaryFunc)g_ascii_strup, GINT_TO_POINTER(-1)); // upper contains AMSTERDAM, SAN FRANCISCO, HELSINKI g_list_free (lst); g_list_free_full (upper, g_free); |
list |
a GList |
|
map_func |
a predicate function |
|
user_data |
a user pointer passed to |
[allow-none] |
GList * gx_list_map_in_place (GList *list
,GXBinaryFunc map_func
,gpointer user_data
,GDestroyNotify free_func
);
Replace each element in list
with the value obtained from applying map_func
to it. Free the old element using free_func
.
list |
a GList |
|
map_func |
a predicate function |
|
user_data |
a user pointer passed to |
[allow-none] |
free_func |
a function to free the replaced element. |
[allow-none] |
gpointer gx_list_fold (GList *list
,GXTernaryFunc fold_func
,gpointer init
,gpointer user_data
,GDestroyNotify free_func
);
Given a list (a, b, c), compute
fold_func (fold_func (fold_func (init
, a), b), c)
gx_list_fold() is useful when computing a value from the elements in a list.
For example, we can use gx_list_fold()
to turn a list of strings into a
single string, wit the elements separated by ", ". This is similar to what
g_build_path()
does, but uses lists:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
static char* chain (const char *s1, const char *s2, const char *sepa) { if (!s1) return g_strdup (s2); else return g_strconcat (s1, sepa, s2, NULL); } GList *lst; char *str; const char* cities[] = { "Amsterdam", "San Francisco", "Helsinki", NULL }; lst = gx_strv_to_list ((gchar**)cities, -1); str = gx_list_fold (lst, (GXTernaryFunc)chain, NULL, "; ", g_free); g_assert_cmpstr (str, ==, "Amsterdam; San Francisco; Helsinki"); g_free (str); g_list_free (lst); |
list |
a GList |
|
fold_func |
a ternary function |
|
init |
the start value |
|
user_data |
a user pointer passed to |
[allow-none] |
free_func |
a function to free the intermediate values. |
[allow-none] |
GList * gx_list_iota (gsize count
,gint start
,gsize step
);
Create a GList with count
numbers starting at start
, and then increasing
by step
; similar to Scheme's SRFI-1's iota procedure.
For example, to get the first 100 even numbers:
1 2 3 4 |
GList *lst; lst = gx_list_iota (100, 0, 2); // do something with lst g_list_free (lst); |
gint
gx_list_sum (GList *list
);
Calculate the sum of a list of integers. This is an optimized shorthand for
1 2 |
sum = GPOINTER_TO_INT(gx_list_fold (list, (GTernaryFunc)gx_plus, GINT_TO_POINTER(0), NULL, NULL)); |
gint
gx_list_product (GList *list
);
Calculate the product of a list of integers. This is an optimized shorthand for
1 2 |
sum = GPOINTER_TO_INT(gx_list_fold (list, (GTernaryFunc)gx_times, GINT_TO_POINTER(1), NULL, NULL)); |