Over the last while I have been asked a few times how to transform a list of values according to some rules,
for example the latest posts in this thread. I have been wondering if this problem is general enough to merit direct support. Thus this RFC.
I propose a new function list_map() that takes a list of items then applies a series of rules to transform or not each item. It returns the transformed list. It does not modify the original list.
The syntax:
Code:
list_map(list_of_values, separator,
rule [, rule]*)
You can have as many rules as you want. A rule is a triple (three arguments):
Code:
boolean to enable the rule, search expression for item, replacement expression
Example: This is a rule that for books authored by someone with Banks in their name, changes all tags 'Science Fiction' to 'SF':
Code:
'Banks' in $authors, '^Science Fiction' in $, 'SF'
The special variable $ is the current item in the list.
Putting it all together we have
Code:
program:
r = list_map($tags, ', ',
'Banks' in $authors, '^Science Fiction' in $, 'SF')
The next example adds a rule to unconditionally delete the tag 'Fiction':
Code:
program:
r = list_map($tags, ', ',
'Banks' in $authors, '^Science Fiction' in $, 'SF',
1, 'Fiction' == $, '')
The 'Fiction' rule is applied unconditionally because the test ('1') is always true.
Final example: I rewrote the example template
in this post of the above mentioned thread to use the proposed list_map() function:
Code:
program:
# show = 'Criminal Minds, Law and Order';
show = 'Pretty Little Liars, Law and Order, Supergirl';
# show = 'Criminal Minds, Law and Order, Supergirl';
# show = $#show;
ao3tags_pair = 'Alex / Emily, Olivia / Alex';
# ao3tags_pair = $#ao3tags_pair;
show1 = '^Criminal Minds$' inlist show && '^Law and Order$' inlist show;
show2 = '^Pretty Little Liars$' inlist show && '^Law and Order$' inlist show;
show3 = '^Supergirl$' inlist show && '^Law and Order$' inlist show;
output = list_map(ao3tags_pair, ',',
show1, $ == "Alex / Emily", "Emily Prentiss / Alex Cabot",
show2, $ == "Alex / Emily", "Emily Fields / Alex Cabot",
show3, $ == "Olivia / Alex", "Alex Danvers / Olivia Benson");
output = list_sort(list_remove_duplicates(output, ','), 0, ',')
The output is
Code:
Alex Danvers / Olivia Benson, Emily Fields / Alex Cabot
The list_map() function isn't particularly hard to implement, but it does create maintenance and documentation headaches that aren't worth it if the function won't be used.
Thoughts?