Compare two variables for equality and inequality

329 views
Skip to first unread message

TonyM

unread,
Nov 6, 2018, 7:03:09 PM11/6/18
to TiddlyWiki
Folks,

I am trying to make a simply comparison between two variables or one variable and a fields content.

eg; <<currentWiki>> and  {{!!wiki-owner}}
or <<currentWiki>> and  <<wiki-owner>>

I simply want a simple test or filter that will be true if they are the same 
and that will be false if they are the same 

Ideally I would use this in the list widget

I am not sure, I think I have a "Mind block" on this and expect any help will get me out of it.

Thanks in Advance
Tony

Mark S.

unread,
Nov 6, 2018, 7:37:25 PM11/6/18
to TiddlyWiki
You mean like ...field:myfield<myvariable>...

?

-- Mark

TonyM

unread,
Nov 6, 2018, 7:54:18 PM11/6/18
to TiddlyWiki
Mark,

Thanks, that may work, funny I have not used the field operator much yet. I have used fieldname[value] before as an elegant narrative way of building filters eg business-size[small] or display-code[yes] however it seems neither fieldname or value can be replaced with a variable or field reference (need to re-test).

Here is my attempt, that is not working

<$list filter="[all[current]has[wiki-owner]get[wiki-owner]]" variable=null>
   "<
<currentWiki>>" = "{{!!wiki-owner}}" ?<br>
   <$list filter="[all[current]field:wiki-owner
<currentWiki>]">
     <
<currentTiddler>> Owns {{Certificate.svg}}
   </$list>
   <$list filter="[all[current]!field:wiki-owner
<currentWiki>]">
      <
<currentTiddler>> Not {{Certificate-not.svg}}
   </$list>
</$list>

I always get Not {{Certificate-not.svg}} regardless of if <<currentWiki>> and {{!!wiki-owner}} match.

Can you see something wrong?

Thanks
Tony

TonyM

unread,
Nov 6, 2018, 8:02:53 PM11/6/18
to TiddlyWiki
Mark,

Your answer should work when comparing a field with a variable, but not a variable with a variable

The Question how to ask
  •  if <<variable1>> equals <<variable2>>
  •  if <<variable1>> not equal <<variable2>>
Is still an open Question for me.

Tony

On Wednesday, November 7, 2018 at 11:37:25 AM UTC+11, Mark S. wrote:

Mark S.

unread,
Nov 6, 2018, 8:30:26 PM11/6/18
to TiddlyWiki
This turns it on it's head a bit, but the other approach is to subtract one variable from another in a filter:

[title<variable1>] -[title<variable2>]

Then the contents of "emptyMessage" become your output for when they do match (which can even be dynamically interpreted text), and the contents between <$list>...</$list> becomes the output when they don't match.

-- Mark

Mark S.

unread,
Nov 6, 2018, 8:39:06 PM11/6/18
to TiddlyWiki
I knew there was something in the back of my mind. Here's a version of the prior method adapted to an example from the SetWidget tiddler:

<$vars test1="abc" test2="abc">
<$set name="myVariable" filter="[
<test1>] -[<test2>]" emptyValue="They match" value="They dont match">
<$text text=<
<myVariable>>/>
</$set>
</$vars>

-- Mark

TonyM

unread,
Nov 6, 2018, 10:33:52 PM11/6/18
to TiddlyWiki
Mark,

Is it fair to call this filter="[<test1>] -[<test2>]" the "Not Same" test, if they are the same Empty Message, if they are not the same its true.


Your suggestion did not work until I wikified the input variables

 a simple true or false icon return
   <$list filter="[is[current]get[wiki-owner]] -[<this-wiki>]" variable=null emptyMessage="{{Certificate.svg}}" >
      {{Certificate-not.svg}}
   </$list>

Thanks to your inspiration I have discovered an even better solution (in my mind)

to Compare two or more variables/titles/fields for equality and inequality

   <$list filter="[<this-wiki>] [{!!wiki-owner}] +[count[]] -[[2]]">
       same
   </$list>

   <$list filter="[<this-wiki>] [{!!wiki-owner}] +[count[]] -[[1]]">
       different
   </$list>
The above method has the advantage of being able to test any two + items that generate a "title" in filter notation.
Note: <this-wiki> was the result of a wikify widget, not a macro
If {{!!wiki-owner}} is empty or missing the result will be "different" which is useful in some cases.

eg;
[{!!fieldname}]  [{tiddlername!!fieldname}]  [<this-wiki>[is[current]get[wiki-owner]] etc...

The advantage here is you can put the Same and Different outcomes where every you want, can have as much or as little wikitext inside each <$list widget resulting for each option.

You can see it would be easy to add three or more values that should be the same", all you must do is to follow the "-[[2]]" with -[[3]] -[[4]] etc... 
or test if one or N are different

Is this cool or what?

Now I am extending this to a "case" statement


Thanks Again
Tony

Mohammad

unread,
Nov 7, 2018, 1:03:21 AM11/7/18
to TiddlyWiki
Hello Tony!
 This is really interesting! I would appreciate if you could put it inside a wiki and give link for future references!
By the way you said the variables cannot be the result of a macro call, why?

-Mohammad

TonyM

unread,
Nov 7, 2018, 3:13:20 AM11/7/18
to TiddlyWiki
I believe it was not until I used wikify to create a variable 

The Following example does not work even although <<currentWiki>> returns the correct value

\define currentWiki() {{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}}

<<currentWiki>>


   
<$list filter="[<currentWiki>] [{!!wiki-owner}] +[count[]] -[[2]]">
       same
{{Certificate.svg}}
   
</$list>
   <$list filter="[<currentWiki>] [{!!wiki-owner}] +[count[]] -[[1]]">
       different {{Certificate-not.svg}}
   </
$list>

How ever when refactored this works

<$wikify name=this-wiki text="<<currentWiki>>">
   <$list filter="[
<this-wiki>] [{!!wiki-owner}] +[count[]] -[[2]]">
       same {{Certificate.svg}}
   </$list>
   <$list filter="[
<this-wiki>] [{!!wiki-owner}] +[count[]] -[[1]]">
       different {{Certificate-not.svg}}
   </$list>
</$wikify>

I stand to be corrected, but that is all I can say at this point.

Regards
Tony

Mohammad

unread,
Nov 7, 2018, 4:01:20 AM11/7/18
to tiddl...@googlegroups.com
I think the problem is with what macro returns!

Now macro returns {{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}} 
But you are right the code does not work!



-Mohammad

Jeremy Ruston

unread,
Nov 7, 2018, 4:17:24 AM11/7/18
to tiddl...@googlegroups.com
Hi Tony

I believe it was not until I used wikify to create a variable 

The Following example does not work even although <<currentWiki>> returns the correct value

\define currentWiki() {{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}}

<<currentWiki>>

The double angle brackets syntax for rendering a macro/variable will wikify the text. So, for example, if the currentWiki variable contained `n//b//n` then you wouldn’t see the double slashes, you’d just see the “b” in italics.

Instead, you can use <$text text=<<currentWiki>>/> which will just display the plain text of the variable/macro.




   
<$list filter="[<currentWiki>] [{!!wiki-owner}] +[count[]] -[[2]]">
       same
{{Certificate.svg}}
   
</$list>
   <$list filter="[<currentWiki>] [{!!wiki-owner}] +[count[]] -[[1]]">
       different {{Certificate-not.svg}}
   </
$list>

How ever when refactored this works

<$wikify name=this-wiki text="<<currentWiki>>”>

The action of the wikify widget is to take the provided text and wikify it offscreen, and then extract the plain text content. So, in this case, the variable "this-wiki” will be set to textual result of wikifying the variable currentWiki. Again, if that variable happens to contain any wikitext markup then it will be processed, and only the resulting plain text will be returned.

To turn to the OP, a reasonable way to check whether a variable and a field or another variable are the same, try this:

<$edit-text tiddler="$:/temp/demo" field="foo"/>
<$set name="bar" value="Avocado">
<$list filter="[<bar>] -[{$:/temp/demo!!foo}]" emptyMessage="Same">
Different
</$list>
</$set>

Use the edit box to experiment with assigning different values to the “foo” field of the demo temp tiddler.

Best wishes

Jeremy.


   <$list filter="[<this-wiki>] [{!!wiki-owner}] +[count[]] -[[2]]">
       same {{Certificate.svg}}
   </$list>
   <$list filter="[
<this-wiki>] [{!!wiki-owner}] +[count[]] -[[1]]">
       different {{Certificate-not.svg}}
   </$list>
</$wikify>

I stand to be corrected, but that is all I can say at this point.

Regards
Tony

On Wednesday, November 7, 2018 at 5:03:21 PM UTC+11, Mohammad wrote:
Hello Tony!
 This is really interesting! I would appreciate if you could put it inside a wiki and give link for future references!
By the way you said the variables cannot be the result of a macro call, why?

-Mohammad

--
You received this message because you are subscribed to the Google Groups "TiddlyWiki" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
To post to this group, send email to tiddl...@googlegroups.com.
Visit this group at https://groups.google.com/group/tiddlywiki.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywiki/962c78fe-6e3d-4860-a2c3-daeba7aeca98%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

TonyM

unread,
Nov 7, 2018, 6:04:47 AM11/7/18
to TiddlyWiki
Jeremy,

Can we establish a "best practice" approach such that when creating a macro to return a value in the first place, say we use the text widget to create "clean" value for use in filters to avoid this kind of issue.

In my use case, I retrieved a value from a data tiddler to set a variable currentWiki, I made this a global macro so I could refer to <<currentWiki>> whenever I needed it. Perhaps I should have used the text widget to ensure this value was already plain text.

Alternativly could filters themself be improved to clean variables before use, or would this have undesirable consequences?

Regards
Tony

Jeremy Ruston

unread,
Nov 7, 2018, 7:58:56 AM11/7/18
to tiddl...@googlegroups.com
Hi Tony

>
> Can we establish a "best practice" approach such that when creating a macro to return a value in the first place, say we use the text widget to create "clean" value for use in filters to avoid this kind of issue.

I’m not sure what issue? The issue here is that you were inadvertently wikifying a value; the fix is to not wikify it.

> In my use case, I retrieved a value from a data tiddler to set a variable currentWiki, I made this a global macro so I could refer to <<currentWiki>> whenever I needed it. Perhaps I should have used the text widget to ensure this value was already plain text.

You should only use <<currentWiki>> to render a global macro if you want the content of the macro to be wikified. If you don’t, then you should use the <$text> or <$view> widgets.

> Alternativly could filters themself be improved to clean variables before use, or would this have undesirable consequences?

What do you mean by “clean” variables?

Best wishes

Jeremy.


>
> Regards
> Tony
>
> --
> You received this message because you are subscribed to the Google Groups "TiddlyWiki" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
> To post to this group, send email to tiddl...@googlegroups.com.
> Visit this group at https://groups.google.com/group/tiddlywiki.
> To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywiki/0122167d-cd8b-4e71-b798-bf48b2041332%40googlegroups.com.

Eric Shulman

unread,
Nov 7, 2018, 12:02:56 PM11/7/18
to tiddl...@googlegroups.com
On Tuesday, November 6, 2018 at 4:03:09 PM UTC-8, TonyM wrote:
I am trying to make a simply comparison between two variables or one variable and a fields content.
eg; <<currentWiki>> and  {{!!wiki-owner}}
or <<currentWiki>> and  <<wiki-owner>>
I simply want a simple test or filter that will be true if they are the same 
and that will be false if they are the same 

Although it might not be obvious, the $reveal widget can do this very easily.  Normally, the $reveal widget is used to compare a "text" value with a value stored in the text field of a specified "state" tiddler, like this:

<$reveal type="match" state="$:/state/SampleReveal1" text="show">
  show this if state tiddler content matches text param
</$reveal>

However, there is an alternative syntax that allows comparisons between any two values: while the "state" param can only use an implied reference to the "text" field of a specified tiddler, the "default" param can use ANY literal, field or variable reference.  Simply OMIT the "state" param and use the "default" param in it's place, like this:

<$reveal type="match" default={{somefield!!sometiddler}} text="show">
   show this if some field in some tiddler matches text param
</$reveal>
or
<$reveal type="match" default=<<somevariable>> text="show">
   show this if somevariable matches text param
</$reveal>

and... since the "text" param also can use ANY field or variable reference, you can use <$reveal> to compare any two variables, like this:

<$reveal type="match" default=<<somevariable>> text=<<someOtherVariable>>>
   show this if somevariable value matches someOtherVariable
</$reveal>

and... you can use any of the valid "type" values to make the comparison, including the recently added LT, GT, LTEQ and GTEQ types.

For example, if you have some "task tiddlers" tagged with "todo" OR "done", you could display conditional output this way:

<$set name="todo" filter="[tag[todo]count[]]">
<$set name="done" filter="[tag[done]count[]]">
<$reveal type="match"   default=<
<todo>> text="0"> There is nothing to do. </$reveal>
<$reveal type="nomatch" default=<
<todo>> text="0">
   <$reveal type="match" default=<
<done>> text="0">      You haven't started.                             </$reveal>
   <$reveal type="LT"    default=<
<todo>> text=<<done>>> You're making progress... keep going!            </$reveal>
   <$reveal type="match" default=<
<todo>> text=<<done>>> You're half way there... take a short break      </$reveal>
   <$reveal type="GT"    default=<
<todo>> text=<<done>>> You've done a lot... but there's still some left </$reveal>
</$reveal>
</$set>
</$set>

Hope this helps.

enjoy,
-e
Eric Shulman
TiddlyTools.com: "Small Tools for Big Ideas!" (tm)
InsideTiddlyWiki: The Missing Manuals

Thomas Elmiger

unread,
Nov 7, 2018, 12:27:13 PM11/7/18
to TiddlyWiki
Maybe too late, but I documented a hack for this about 13 months ago:

https://tid.li/tw5/hacks.html#ifAisB%20%E2%80%93%20Compare%20if-then-else%20Style%20in%20Wikitext

All the best,
Thomas

Mark S.

unread,
Nov 7, 2018, 1:00:12 PM11/7/18
to TiddlyWiki
This is great to know, but really, really understated in the documentation. I'm thinking that there should be at least a line or two in the RevealWidget documentation, and maybe an example, that advertises this ability. Especially since the RevealWidget, unlike filter syntax, now has a bunch of comparison operators.

Thanks!
-- Mark

Mohammad

unread,
Nov 7, 2018, 2:44:28 PM11/7/18
to TiddlyWiki
Thank you Eric! great explanation!

Thank you Thomas for such great collection of TW codes!

Mark, I totally agree with you! I am actually learning TW in this forum!
It is very hard or impossible to learn such features from tiddlywiki.com!

- Mohammad

TonyM

unread,
Nov 8, 2018, 12:13:56 AM11/8/18
to TiddlyWiki
Jeremy,

Interesting, I have never heard it put this way.


You should only use <<currentWiki>> to render a global macro if you want the content of the macro to be wikified.

I need to think about that. If a variable in the list widget, wikify or set widget is used they will also be wikified <<asavar>>?

If you look back to my example I solved the problem by using wikify, which seems to contradict the above. I am sure I am missing a subtle detail.

Thank
Tony

TonyM

unread,
Nov 8, 2018, 12:25:13 AM11/8/18
to tiddl...@googlegroups.com
Jeremy, Says


You should only use <<currentWiki>> to render a global macro if you want the content of the macro to be wikified. If you don’t, then you should use the <$text> or <$view> widgets.

This confuses me, because I made a global variable/macro called currentWiki to pull a value from a data tiddler for the current wiki name. I don't want to fuss with the details just use the result globally.

I want to use this "macro/variable" where ever I need it, in a filter, in text, as a link to a tiddller of that name etc..  Should I have used the text widget in the currentWiki macro so the result is the same if wikified or not?

The "best practice" idea is to publish, promote and support people by giving the "best practice" method we know for addressing this "issue".

Eg

\define currentWiki() {{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}} 

Changed to 

\define currentWiki() <$wikify name=wiki-name text="{{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}}"><$text text=<<wiki-name>> /></$wikify>


<<currentWiki>>


<$list filter="[all[current]has[wiki-owner]]">

   
<$list filter="[<currentWiki>] [{!!wiki-owner}] +[count[]] -[[2]]">

       
{{Certificate.svg}}
   
</$list>

   <$list filter="[<currentWiki>] [{!!wiki-owner}] +[count[]] -[[1]]">
       {{Certificate-not.svg}}
   </
$list>
</$list>

<<currentWiki>> now returns a clearly text value yet the below continues to give a Certificate-not.svg result when {{!!wiki-owner}} has the same value?

Yours Sincerely Perplexed.

Regards
Tony


TonyM

unread,
Nov 8, 2018, 1:30:17 AM11/8/18
to TiddlyWiki
Eric,

That is really cool, this simpler use of the reveal, This surely deserves being included in examples on TiddlyWiki.com?

Thanks
Tony

TonyM

unread,
Nov 8, 2018, 6:51:04 AM11/8/18
to TiddlyWiki
For people passing this way,

Eric's tip translated to my application looks like this, need not separate definition of currentWiki

<$reveal type="match" default={{!!wiki-owner}} text={{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}}>
   {{Certificate.svg}} Match
</$reveal>


<$reveal type="nomatch" default={{!!wiki-owner}} text={{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}}>
    {{Certificate-not.svg}} No Match
</$reveal>



 but that would be nice to replace {{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}} with <<currentWiki>> but it does not work

mauloop

unread,
Nov 10, 2018, 3:19:46 AM11/10/18
to TiddlyWiki
Hi, Tony.

Thanks for your post. It raised a very interesting thread. I learned a lot reading it.
 
 but that would be nice to replace {{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}} with <<currentWiki>> but it does not work

It's true. I tested exactly your examples, even if I already knew you was right, since I experienced something similar many times. It is frustrating to have "variables" that sometimes work as expected and sometimes not.

I learned that "variables" defined by wikitext macros are merely text substitutions. I though that they were wikified or not  it depends on the context (ie: in the tiddler body they are wikified while as a widget param values they are not)

Having "$:/PSaT/wikimanager/wiki-tiddler##wiki-title" and "!!wiki-owner" set to the same value I tested the following:

title: $:/PSaT/wikimanager/wiki-tiddler
type
: application/x-tiddler-dictionary


wiki
-title: mau

title: Compare lab
wiki
-owner: mau


\define currentWiki() {{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}}


----
!!currentWiki macro output


<<currentWiki>>


----
!!Using field reference


<$reveal type="match" default={{!!wiki-owner}} text={{$:/PSaT/wikimanager/wiki-tiddler##wiki-title}}>

   
Match
</$reveal>


<$reveal type="nomatch" default={{!!wiki-owner}} text={{$:/
PSaT/wikimanager/wiki-tiddler##wiki-title}}>

   
No Match
</$reveal>


----
!!Using currentWiki macro


<$reveal type="match" default={{!!wiki-owner}} text=<<currentWiki>> >
   Match
</
$reveal>


<$reveal type="nomatch" default={{!!wiki-owner}} text=<<currentWiki>> >
   
No Match
</$reveal>


----
!!Using set widget


<$set name="currentWiki" value={{$:/
PSaT/wikimanager/wiki-tiddler##wiki-title}}>


<$reveal type="match" default={{!!wiki-owner}} text=<<currentWiki>> >
   
Match
</$reveal>


<$reveal type="nomatch" default={{!!wiki-owner}} text=<<currentWiki>> >
   No Match
</
$reveal>


</$set>


----
!!Using set widget + currentWiki macro


<$set name="currentWiki" value=<<currentWiki>> >


<$reveal type="match" default={{!!wiki-owner}} text=<<currentWiki>> >
   Match
</
$reveal>


<$reveal type="nomatch" default={{!!wiki-owner}} text=<<currentWiki>> >
   
No Match
</$reveal>


</
$set>

"Compare lab" tiddler shows the following output:

compare.JPG


I don't understand Jeremy explanation:

You should only use <<currentWiki>> to render a global macro if you want the content of the macro to be wikified.

It seems that in the previous examples it is not always true.

I also would like to find a best practice, I mean a consistent approach to deal with "variables".

Mohammad

unread,
Jan 31, 2019, 1:24:53 PM1/31/19
to TiddlyWiki
Reply all
Reply to author
Forward
0 new messages