See if a "list of tiddlers" is same as tiddlers in a "list field"

59 views
Skip to first unread message

S. S.

unread,
Feb 25, 2019, 4:13:15 PM2/25/19
to TiddlyWiki

I have a feeling someone would have solved this before.
I want to know if a "list of tiddlers" match or do not match the tiddlers in a "list field"

A tiddler has a list field: {{!!list}} = [[A]] [[B]] [[C]]

A list-of-tiddlers is made.

<$set name="list-of-tiddlers" filter="[[C]] [[B]] [[A]]">

CODE comparing {{!!list}} with <
<list-of-tiddlers>>
resulting in either <
<match>> or <<no-match>>

</$set>


Thanks!

TonyM

unread,
Feb 25, 2019, 4:42:31 PM2/25/19
to TiddlyWiki
S s

A possible trick, in a filter generate the titles in one and remove the title found in the other. Emptyvalue or emptymessage will mean a match, including when both are empty.

If not empty The result will be tiddlers not found in either list.

To simplify it use the subfilter operator for both sets of tiddler and try -[subfilter[name]

Eg untested
"[subfilter<myfilter>] -[subfilter{!!list}]"

Regards
Tony

S. S.

unread,
Feb 25, 2019, 4:43:33 PM2/25/19
to TiddlyWiki
Funny, how so often, when you write out the question clearly enough for others to understand it, it becomes clearer to yourself how it can be solved.

Would this below solution break in certain situations?


{!!list}} = [[A]] [[B]] [[C]]

<$set name="check-list" filter="[[C]] [[B]] [[A]] +[sort[]]">
<$set name="check-field" filter="[all[current]list[]sort[]]">
   <$list filter="[
<check-list>] -[<check-field>]" emptyMessage="match">
      no-match
   </$list>
</$set>
</$set>

S. S.

unread,
Feb 25, 2019, 5:31:58 PM2/25/19
to TiddlyWiki
Tony, your suggestion is close. What it tells me is if <myfilter> contains {!!list} - which is actually also useful to me!

Mark S.

unread,
Feb 25, 2019, 5:41:46 PM2/25/19
to TiddlyWiki
I think you also need to do a second run, checking for check-field > check-list. I don't think the sorts will matter one way or the other for the detection. I feel that you should be using subfilter or enlist like Tony suggested. Your examples don't have spaces in them. Maybe try some with spaces.

Good luck

-- Mark

TonyM

unread,
Feb 25, 2019, 5:50:01 PM2/25/19
to TiddlyWiki
S S

Did you use the actual subfilter operator?

I would like to chase this to an elegant and adaptable method, because it is important.

Regards
Tony

S. S.

unread,
Feb 25, 2019, 5:51:40 PM2/25/19
to TiddlyWiki
Actually, I jumped the gun there, as I was testing using the enlist operator when I read your post:

This is what would give : {!!list} contains <myfilter>

{{!!list}} = [[C A]] [[A C]] [[B B]] x

field CONTAINS list:
<$set name="check-list" filter="[[C A]] [[B B]] [[A C]]">
   
<$list filter="[enlist<check-list>] -[enlist{!!list}]" emptyMessage="MATCH">
   NO
-MATCH
   
</$list>
</
$set>

S. S.

unread,
Feb 25, 2019, 6:05:17 PM2/25/19
to TiddlyWiki
Hi Mark,

By sorting, it compares one long string (the full sorted list of tiddlers) against the other full sorted list of tiddlers - for an exact match.
I ran a few test variations and it hasn't broken yet!

Perhaps 2 runs as you suggest is safer? I'm not sure which way won't break. Perhaps neither will.

TonyM

unread,
Feb 25, 2019, 6:47:18 PM2/25/19
to TiddlyWiki
S S ,

Yes exactly. I also tested
[enlist<list-of-tiddlers>] -[enlist{!!list}]

where <list-of-tiddlers> was a macro

I am keen to extend this to unions, not in either set etc...

Regards
Tony

Mark S.

unread,
Feb 25, 2019, 6:57:20 PM2/25/19
to TiddlyWiki
I don't believe you need the sort -- TW will do that internally when it process the lists.

Your original question asked to compare if two lists were the same. With only one set of runs, it will check only that one list is contained in the other.

-- Mark

S. S.

unread,
Feb 25, 2019, 7:23:19 PM2/25/19
to TiddlyWiki
Tony,

Trying out Mark's suggestion, I can't understand why this fails :

{{!!list}} = [[C A]] [[A C]] [[B B]] y
<$set name="check-list" filter="[[C A]] [[B B]] [[A C]] x">
   <$list filter="[enlist
<check-list>] -[enlist{!!list}] ~[enlist{!!list}] -[enlist<check-list>]" emptyMessage="MATCH">
      NO MATCH
   </$list>
</$set>

I haven't needed to use the ELSE run prefix ~ before so I tried both ways (extra ~[[ brackets ]] around the ~ prefix, and both ways failed:

<$set name="check-list" filter="[[C A]] [[B B]] [[A C]] x">
   <$list filter="[enlist
<check-list>] -[enlist{!!list}] ~[[enlist{!!list}] -[enlist<check-list>]]" emptyMessage="MATCH">
      NO MATCH

   </$list>
</$set>

Confused.

TonyM

unread,
Feb 25, 2019, 8:09:53 PM2/25/19
to TiddlyWiki
S S

What are you trying to do?

~[enlist{!!list}] is correct

Lets convert to plane language
filter="[enlist<check-list>] -[enlist{!!list}] ~[enlist{!!list}] -[enlist<check-list>]

List each item in check-list, removing those that are in !!list, If and only if the resulting list is now empty (because they match), list the items in !!list, and remove those in check-list, so the result must be empty (because we are only here because If and only if the first resulting list is empty 

Regards
Tony

S. S.

unread,
Feb 25, 2019, 8:30:00 PM2/25/19
to TiddlyWiki
Tony,

This is how I am looking at it:

If var check-list contains: A
and {!!list} contains: A B
[[A]] -[[A]] -[[B]] = empty
so  [enlist<check-list>] -[enlist{!!list}] gives an empty result
This part is working fine.

NEXT

[[A]] [[B]] -[[A]] = [[B]]
[enlist{!!list}] -[enlist<check-list>] should give a NOT EMPTY result, but it gives an EMPTY result!

The 2nd part of the filter is not evaluating the way I expect it to.
This is what is confusing me.

Mark S.

unread,
Feb 25, 2019, 9:48:13 PM2/25/19
to TiddlyWiki
Well, I was wrong, and I was right.

You do need two filter runs, but unfortunately they can't be run in the same filter widget. AFAIK, there are no tools for grouping runs. The "else" operator only works on a single run, so you can't use that either.

Here's my solution below. It puts the 2nd check in a macro that gets called from the first run. Oh, the macro should probably be tweaked to limit it's output to one tiddler.

-- Mark


\define check2()
<$list filter="[enlist{!!list}]  -[enlist<check-list>]" emptyMessage="MATCH!">
      UNMATCHED
</$list>
\end


<$set name="check-list" filter="[[C A]] [[B B]] [[A C]] ">
   <$list filter="[enlist<check-list>] -[enlist{!!list}] +[limit[1]]" emptyMessage=<<check2>>  >
    UNMATCHED
</
$list>
</$set>


Reply all
Reply to author
Forward
0 new messages