An odd compare operator result

I am trying to make my backlinks display more intelligent, in so far that only display links if the result from the backlinks operator is gt 0. I realise that I am trying to be too clever in that the TLSdisplaylinks procedure will only be invoked on a non empty list. However, that still does not explain the result from the compare operator.

With no comparison, the result is (ie. backlinks on its own matches my code result).

Now we add the compare operator code.

<!-- extracts backlinks from the current tiddler -->
\procedure TLSbacklinks()
Linked from
<br>
<!--only used for debugging
<<list-links filter:"[all[current]backlinks[]]" >>
-->

<<list-links filter:"[all[current]backlinks[]]" >>

<$list filter="[all[current]backlinks[]compare:number:gt[0]]" >
 <<TLSdisplaylinks>>
</$list>
\end

Using the above code, the result is missing the entries after Carriages

Screenshot 2025-10-31 at 15.14.50

If I change the code to, removing the text ‘number:’

<!-- extracts backlinks from the current tiddler -->
\procedure TLSbacklinks()
Linked from
<br>
<!--only used for debugging
<<list-links filter:"[all[current]backlinks[]]" >>
-->

<<list-links filter:"[all[current]backlinks[]]" >>

<$list filter="[all[current]backlinks[]compare:gt[0]]" >
 <<TLSdisplaylinks>>
</$list>
\end

the result is now missing the first three entries, before Fort Glanville

If I insert the missing : in the compare statement, the result is the same as the first result, entries after Carriages is missing.

NB: I display the result from using just a plain backlinks operator call to allow comparison with what should be displayed from my call.

I can’t explain this result.

For your information, TLSdisplaylinks is (and tis works correctly)

<!--displays the links depending on tiddler type, from the supplied list of tiddlers -->
\procedure TLSdisplaylinks()
    <% if [<currentTiddler>prefix:title[MGA]caption[History]] %>
          <$link to=<<currentTiddler>> >
           History: <$text text={{{ [<currentTiddler>get[parentGun]get[caption]]  }}}/>
           </$link>
           <br>
     <% elseif [<currentTiddler>prefix:title[MGA]caption[Local History]] %>
          <$link to=<<currentTiddler>> >
           LocalHistory: <$text text={{{ [<currentTiddler>get[parentGun]get[caption]]  }}}/>
           </$link>
           <br>
      <% elseif [<currentTiddler>prefix:title[MGA]caption[Gallery]] %>
          <$link to=<<currentTiddler>> >
           Gallery: <$text text={{{ [<currentTiddler>get[parentGun]get[caption]]  }}}/>
           </$link>
           <br>
       <% elseif [<currentTiddler>prefix:title[MGA]caption[Technical]] %>
          <$link to=<<currentTiddler>> >
           Technical: <$text text={{{ [<currentTiddler>get[parentGun]get[caption]]  }}}/>
           </$link>
           <br>
      <% elseif [<currentTiddler>prefix:title[MGA]caption[Map]] %>
          <$link to=<<currentTiddler>> >
           Map: <$text text={{{ [<currentTiddler>get[parentGun]get[caption]]  }}}/>
           </$link>
           <br>
       <% elseif [<currentTiddler>tag[All Guns]] %>
          <$link to=<<currentTiddler>> >
           All Guns: <$text text={{!!caption}} />
           </$link>
           <br>
      <% elseif [<currentTiddler>tag[Gun Type]] %>
          <$link to=<<currentTiddler>> >
           Gun Type: <$text text={{!!title}} />
           </$link>
           <br>
      <% elseif [<currentTiddler>tag[Fort]] %>
          <$link to=<<currentTiddler>> >
           Fort: <$text text={{!!title}} />
           </$link>
           <br>
      <% elseif [<currentTiddler>tag[Ship]] %>
          <$link to=<<currentTiddler>> >
           Ship: <$text text={{!!title}} />
           </$link>
           <br>
      <% elseif [<currentTiddler>tag[Manufacturer]] %>
          <$link to=<<currentTiddler>> >
           Manufacturer: <$text text={{!!title}} />
           </$link>
           <br>
      <% elseif [<currentTiddler>caption[Ammunition]] %>
         <$link to=<<currentTiddler>> >
           Ammunition: <$text text={{!!title}} />
           </$link>
           <br>
       <% elseif [<currentTiddler>caption[Carriages]] %>
         <$link to=<<currentTiddler>> >
           Carriages: <$text text={{!!title}} />
           </$link>
           <br>
       <% endif %>
\end

Any ideas?

bobj

Searching around, I saw the attributes to the $list widget and realise it has its own emptyMessage attribute and the ability to link results to a specified number.

The limit attribute would be useful for those large lists but I can not see a way of returning a set number from the middle of a list, ie. paging 20 at a time.

Still doesn’t explain the compare result though.

bobj

backlinks[] produces a LIST of tiddler titles… not a number.

To suppress the display of backlinks, you need to count[] the number of titles it returns and then check to see if that number is 0.

Try this:

<$let num={{{ [all[current]backlinks[]count[]] }}}>
<$list filter="[all[current]backlinks[]] :filter[<num>!match[0]]">
 <<TLSdisplaylinks>>
</$list>

Note that since you are only concerned with checking for “0 links”, you don’t need to use the compare filter operator… a simple !match[0] is sufficient.

The above could also be written like this:

<$list "[all[current]backlinks[]count[]!match[0]]" variable=none>
<$list filter="[all[current]backlinks[]]"><<TLSdisplaylinks>></$list>
</$list>

-e

I am still to understand the main question however you can achieve the above via the index value on the set widget, where the set widget value is derived from a list variable or filter. then you use the range operator to provide the n to n+20 number to the set widgets select attribute. first is zero.

List paging has being addressed a few times in the community.

the list widget allows you to simultaneously retrieve an item count using its counter attribute, first is 1, or now also a limit.

@EricShulman , in your example, there are two calls to backlinks being processed so this could be an expensive overhead.

I assume I could always return the result to a <<variable>> and then use the count[] operator on that variable to get the number?

Still, in my case, I would have expected compare[] to fail if it could recognise that the comparison expression was illogical.

Also, something that has been needling me for some time, how can I set the value of a variable to a new value after the $set or $let statement to create it with an initial value? Used in a loop, say

$let flag=false
$list …
if flag = false then
do things
flag = true
end if
do some more things
/$list

Good to talk the other day and put a face to the name.

bobj

Ah I see @TW_Tones I had not come across that before, thanks for pointing it out.

The main question was trying to understand why the different compare calls resulted in different results. Especially now that @EricShulman has pointed out the count operator merely returns the actual number. I assumed the list was also available from the operation step before actually counting.

bobj

Something like this:

<$set name="blinks" filter="[all[current]backlinks[]]">
<$list "[enlist<blinks>count[]!match[0]]" variable=none>
<$list filter="[enlist<blinks>]"><<TLSdisplaylinks>></$list>
</$list>
</$set>

The $set widget runs the filter and stores the results as a space-separated bracketed list in the blinks variable. Then, the enlist<blinks> operator retrieves that list as separate items, so you can use [enlist<blinks>count[]] to get the number of list items. Note that the enlist operator is very efficient since it doesn’t actually search through all the tiddlers again… it just uses the list of tiddlers that was stored in the variable.

Also note that you can’t use <$let blinks={{{ [all[current]backlinks[]] }}}> to get the list of backlinks because the $let widget assignment will only store the first item from the list.

-e

What I am not clear on is [all[current]backlinks[]] if it returns no results, the contents of a list widget never display anyway, so you dont need to code for a count[]match[0] or count[]!match[0] and doing this makes the emptyMessage redundant. I have placed a “list filter or if” inside a list that only displays, the heading when the counter = 1.

just saying

When the input to the compare operator is entirely non-numeric, it is treated as if it is a “0”. However, if the input STARTS with some numbers, then it uses the numbers and ignores the rest.

In your example data, “.45 inch…” has a numeric value of .45, and “64 Pounder…” has a numeric value of 64, but the remaining backlink TITLES start with non-numeric text, so they all have a value of 0 and are therefore skipped by the compare.number.gt[0] filter.

-e

Yes I realise that now @TW_Tones but when in the midst of coding I forgot to check the attributes for the list widget. As I said in a subsequent post, I was trying to be too clever.

Now have things working as I envisaged.

Thanks for your pointers though, my ‘useful’ wiki is filling up.

Bobj

Ah, that explains things. Thanks for taking the time @EricShulman

Bobj