Re: useful list functions
- From: John Cupitt <john cupitt ng-london org uk>
- To: gtk-devel-list gnome org
- Cc: Maciej Stachowiak <mjs eazel com>
- Subject: Re: useful list functions
- Date: Mon, 07 Aug 2000 11:28:15 +0100
Maciej Stachowiak wrote:
> /* Just like `map' in Lisp, Scheme or Perl, i.e. like for_each but
> return a list of the results. (non-destructive) */
I realise this has zero change of inclusion, but I thought I'd share my
favorite two 'missing' g_?list_*() functions with you as well ;-)
The idea for these two functions is that, like lisp, explicit recursion
or iteration over lists is a bad thing, and should be encapsulated in
higher order functions. I use this pair, and (I don't think) my app (not
small, 60k lines) has any list loops in it at all.
typedef gpointer (*ListMapFn)( gpointer, gpointer );
gpointer slist_map( GSList *list,
ListMapFn user_func, gpointer user_data );
This is like for_each, but has a 'bail out'. If user_func returns NULL,
_map() tries the next element. If user_func returns non-NULL, the loop
stops and slist_map() returns that value as its result. If user_func
returns NULL for all elements, _map() returns NULL.
You can express search-for-item loops, repeat-until-full loops and
others. Also handy for trapping errors .. eg. "scan all input fields ...
if a field contains a format error, bail out immediately and pop up an
alert box over the offending field."
typedef gpointer (*ListFoldFn)( gpointer, gpointer, gpointer );
gpointer slist_fold( GSList *list,
gpointer start, ListFoldFn user_function, gpointer user_data );
This is like _map(), but it folds the list up with a dyadic function.
For example, for the input list:
fn (fn (fn start a) b) c
ie. fn is given two arguments: an accumulated value, and the next list
element. 'start' is the initial value for the accumulator. Given an
empty list, the function returns 'start'. Like _map(), _fold() has a
bail out: this time if user_func returns NULL, iteration terminates
immediately and the whole function returns NULL.
Using fold you can find the maximum value in a list, write Maciej's
_map() function, sum a list, erm, and other stuff.
There are a few variants as well: slist_map2 and slist_fold2 take two
user_data arguments. slist_map_rev() maps in reverse order.
slist_foldr() folds a list with a right-associative function.
John Cupitt, email@example.com, +44 (0)20 7747 2570
VASARI Lab, The National Gallery, Trafalgar Square, London, WC2N 5DN
] [Thread Prev