Conditionally transforming a value inside a filter

I’m sure I’m missing something simple, but how can my filter either—based on a regex condition—apply a transformation to a value or leave it intact?

In a much simplified example, I supply a single character, and if it’s a-z, I upper-case it, otherwise I leave it alone. I feel like this should be trivial, so I think I’m having one of my periodic syntax brain farts, but I am stuck.

[[a]my.operator[]] ==> "A"
[[7]my.operator[]] ==> "7"

While this doesn’t absolutely have to be in a single filter, it would definitely be preferable. I want to put it in a function so I can use it as a filter operator. I suppose that with the function Operator, I can probably call out to a separate procedure or some such, but a single filter would be helpful.

Am I right? Is there a simple way to do this that I’m overlooking?

I only dabble in regex, so there may be a definition that doesn’t require square brackets, but here’s what I’d try:

\function .func(lc:"[a-z]") [regexp<lc>uppercase[]] ~[all[]]

{{{ [[a].func[]] }}}
1 Like

Of course. Thank you. What I was mostly missing was making the else clause a separate filter run. I was trying to inline it, and nothing worked.

1 Like

Or I am…

[[a]uppercase[]]

The :map[...] filter run is used to “apply a transformation” to each input item. Combined with a regexp[…] test, you can make the transformation conditional.

For example, suppose you are given a list which should contain only integers, and you want to replace any non-integer values with “NaN” (Not a Number), you could write:

<$let items="1 3.1 5 x 4.3 7 y 8 11 25.5 12">

{{{ [enlist<items>] :map[<currentTiddler>regexp[\D]then[NaN]else<currentTiddler>] }}}

and the output would be:

1
NaN
5
NaN
NaN
7
NaN
8
11
NaN
12

You could then remove the “NaN” items, by adding +[!match[NaN]] after the :map[...], like this:

{{{ [enlist<items>]
   :map[<currentTiddler>regexp[\D]then[NaN]else<currentTiddler>]
   +[!match[NaN]] }}}

enjoy,
-e

1 Like

Remember,

The real case has me applying encodeuricomponent selectively to those characters of a string that match the regex / [^a-z0-9\-\.\_\~\!\$\&\'\(\)\*\,\=\@\/\?]/. I’m close to getting it working based on what @etardiff shared above. I’ll share when I have it completed.

Thank you. I was planning on using map further in this process. (I’m a big fan of functional programming; map is one of my stalwarts.) The rest is very much like what I was trying to do but getting stuck.

If I didn’t want a static NaN there but the result of calling a function/operator on my data, perhaps something like uppercase, is there a straightforward syntax to do so, so that I get something like

1
3.1   -- uppercased
5
X     -- uppercased
4.3   -- uppercased
7
Y     -- upercased
8
11
25.5  -- uppercased
12

?

This doesn’t work:

{{{ [enlist<items>] :map[<currentTiddler>regexp[\D]then<uppercase>else<currentTiddler>] }}}

and this is not even legal syntax:

{{{ [enlist<items>] :map[<currentTiddler>regexp[\D]then[function[uppercase]]else<currentTiddler>] }}}

This?

{{{ [enlist<items>] :map[<currentTiddler>regexp[\D]uppercase[]else<currentTiddler>] }}}

Try this:

{{{ [enlist<items>] :map[<currentTiddler>regexp[\D]function[uppercase]else<currentTiddler>] }}}

-e

Are you experimenting with wikitext filters to convert them to “slugs”. If yes – IMO In the end slugs should be “all lowercase”. Just my thought.

Thank you both. I don’t know why I thought I needed the then, but these work great!

No, I was rebuilding my Permalinks PR in wikitext, removing all the constants that made the code flexible but hard to read. It seems to be in relatively good shape, although there are still a few bugs:

SimplerPermalinks.json (1.7 KB)

(I agree that slugs should be lower-case… which is part of my reason for worrying about the implications for duplicates)


Thank you very much, everyone! You’ve all been a great help!

1 Like

I do. Other-language baggage. I do it “all the time”, until I remember, then and else are not the cohorts you think they are, they’re individual, independent operators.

One day, I’ll remember going in instead of on my way out… :roll_eyes:

You’re probably right. And I’ve probably done it before too.

But the better I get with TW syntax, the more these lapses surprise me!