## Functional GLists

Functional GLists — using GList with a functional flavor

## Functions

 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 ()

## Description

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);```

## Functions

### gx_list_filter ()

```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);```

#### Parameters

 list a GList pred_func a predicate function user_data a user pointer passed to `pred_func` .

#### Returns

the filtered list.

### gx_list_every ()

```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);```

#### Parameters

 list a GList pred_func a predicate function user_data a user pointer passed to `pred_func` .

#### Returns

`TRUE` if pred_func returns `TRUE` for every element in `list` ; `FALSE` otherwise.

### gx_list_any ()

```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);```

#### Parameters

 list a GList pred_func a predicate function user_data a user pointer passed to `pred_func` .

#### Returns

`TRUE` if pred_func returns `TRUE` for at least one element in `list` ; `FALSE` otherwise.

### gx_list_filter_in_place ()

```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`

#### Parameters

 list a GList pred_func a predicate function user_data a user pointer passed to `pred_func` . free_func function to free elements that are filtered-out.

#### Returns

the filtered list, consisting of the remaining elements of `list` . Note that the start of the list may have changed.

### gx_list_take ()

```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);```

#### Parameters

 list a GList n the number of elements to take

#### Returns

a new list with up to n elements; free with `g_list_free()`.

### gx_list_take_in_place ()

```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`

#### Parameters

 list a GList n the number of elements to take free_func function to free the removed elements.

#### Returns

the list reduced to up to `n` elements.

### gx_list_skip ()

```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`

#### Parameters

 list a GList n the number of elements to take

#### Returns

a new list with up to n elements; free with `g_list_free()`.

### gx_list_skip_in_place ()

```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`

#### Parameters

 list a GList n the number of elements to take free_func function to free the removed elements.

#### Returns

a list with up to n elements; free with `g_list_free()` or `g_list_free_full()`, depending on the the.

### gx_list_map ()

```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);```

#### Parameters

 list a GList map_func a predicate function user_data a user pointer passed to `map_func` .

#### Returns

the list with mapped values. Whether to free with `g_list_free()` or with `g_list_free_full()` depends on `map_func` .

### gx_list_map_in_place ()

```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` .

#### Parameters

 list a GList map_func a predicate function user_data a user pointer passed to `map_func` . free_func a function to free the replaced element.

#### Returns

the list with mapped values.

### gx_list_fold ()

```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);```

#### Parameters

 list a GList fold_func a ternary function init the start value user_data a user pointer passed to `fold_func` . free_func a function to free the intermediate values.

#### Returns

the computed value.

### gx_list_iota ()

```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);```

#### Parameters

 count number of elements to generate start the start value step the step size, must be > 0

#### Returns

a list with numbers. Free with `g_free()`.

### gx_list_sum ()

```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));```

#### Parameters

 list a GList

#### Returns

the sum of the integers in `list` .

### gx_list_product ()

```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));```

#### Parameters

 list a GList

#### Returns

the product of the integers in `list` .