arrays in field manipulation

100 views
Skip to first unread message

Paul Netsaver

unread,
Jun 21, 2018, 8:52:00 AM6/21/18
to tiddl...@googlegroups.com
Hi,
I'm trying to have multiple fields whose content is an array, and I need help on how to manipulate them.
Let's have a tiddler about a person (tiddler) Alfred, having Burt, Connie, Danny as relatives.
The relationship of B,C,D to A is respectively: son, wife, brother.
So I would like to use two fields: 'relatives' and 'role' to describe the situation. Note that 'role' is not absolute, but limited to Alfred.
I would build two arrays as fields:
relatives: 'Burt Connie Danny' and
roles: 'son wife brother';
There is more than one question about:
  1.  can I put a separator like any array, so that I'm able to separate items or I'm forced to use a space as separator? Otherwise I will never be able to insert double names, as 'Mary Ann'. Or there's an escaping character, as '\'.
  2. can I refer to a single name as element of the array?  Something link {{ !!relatives[2] }} or {{ !!roles[1] }}. I've tried widgets like <$list> and <$view> but I don't know how to address single fields. Or maybe assign the field to a variable and access the variable (...how?)
I tried also to write a table associating relatives and roles and also that was not so easy (I used a technique from stephenteacher.tiddlyspot.com):

<table>
 
<tr><th>relatives</th><$list filter="[list[!!relatives]]" >
 <td><$transclude field="title"/></td>
 </$list>
</tr>
 
<tr><th>roles</th><$list filter="[list[!!roles]]" >
 <td><$transclude field="title"/></td>
 </$list>
</tr>
</table>

This works because the list commands are independent each other as they are on different rows.. but I want to list the elements by rows, not by columns, so I should do something like:

<table>
 
<tr><th>relatives</th><th>roles</th></tr>
 
<$list filter="[list[!!relatives]]">
 </tr>
    <td><$transclude field="title"/></td>
    <td><$transclude field="roles field of Alfred tiddler"/></td>
  </tr>
  </$list>
</table>

I understand that <$list> command assumes a list of tiddlers (not generic arrays) as input, so it uses title field of (non existing) relatives tiddlers.
Is there another more 'trivial' technique as for arrays? Like:

<table>
 
<tr><th>relatives</th><th>roles</th></tr>
 <$for index="i=1:length(relatives)">
 
</tr>
   
<td><$view field="relatives[i]"/></td>
   
<td><$view field="roles[i]"/></td>
 
</tr>

  </$list>
</table>


Any suggestion is welcome...

Thanks and regards, 
Netsaver, Rome (IT)






Mark S.

unread,
Jun 21, 2018, 10:39:38 AM6/21/18
to TiddlyWiki
I think I would start by restructuring the data differently. Even in a robust language like javascript I would avoid storing data in two parallel "arrays" like you are doing. It would be so easy to get them out of synch.

Maybe keep the list of family members, but then have the field "roles" contain the name of a data tiddler that describes the relationship:

roles: Burts family roles

Burts family roles: (data tiddler)

Burt: son
Connie: wife
Danny: brother

Or keep the list of family members, but then have a series of fields that describe roles:

role-sons: [[Cycil de Mille]] [[Cyrano de bergerac]]
role-wives: Connie
role-brothers:Danny [[Dante Alighieri]]

You can use the fields operator to get a list of all fields and the prefix operator to limit that selection to just ones marked "roles-" .

There's no arrays in TW parlance, but there are lists and list fields. See the tiddler "Filter Operators" at tiddlywiki.com and review list, enlist, listop operators and string operators to get an idea of the tech available.

AFAIK, there's no indexing lists, but there are other tools. If you have items in the list with spaces in the name, surround the name with double square brackets as in the examples above.

Also, you can nest <$lists> inside lists, linking the inner ones with the 'all[current]' filter operator to be driven by the outer ones.

So, I recommend picking a data structure that matches the way TW works (probably the 2nd method, thought the first method corresponds to better database design).

But maybe someone will come along with a more straight-forward solution. So rather than diving into an example, let's see what others say.

-- Mark

@TiddlyTweeter

unread,
Jun 21, 2018, 11:10:02 AM6/21/18
to TiddlyWiki
Paul, its a very interesting question I find.

I have no skill for a detailed answer.

The one thing I would advise is to consider in using arrays that though TW can emulate a "flat-file" database, emulating a relational or hierarchical database would be pretty complicated and likely not worth the effort.

But, Data Tiddlers are worth looking to if you need to do flat-data at volume (i.e. A Data Tiddler with many individual record [each record (line) can be treated as a Tiddler]). For a Data Tiddler "array" you need a "splitter" to reconstitute the data.

Mark S. pointed towards "fields" in Tiddlers one by one. That is likely the best documented route.

Josiah.

Ste Wilson

unread,
Jun 21, 2018, 1:51:51 PM6/21/18
to TiddlyWiki
"I tried also to write a table associating relatives and roles and also that was not so easy (I used a technique from stephenteacher.tiddlyspot.com)"

You did? AWESOME!

I did that... AWSOME!! (I think it came with a lot of help from the good people here) :)

Mark S.

unread,
Jun 21, 2018, 3:13:18 PM6/21/18
to TiddlyWiki
Here's a file you can drag and drop into your TW demonstrating the 2nd method I mentioned. I'm not saying it's the best method, but it was easiest to create ;-)

Notice that you don't need a "relatives" field -- all the relative information is already contained in the roles fields. It prevents mistakes if you don't have to be worrying about keeping different fields in synch.

If you have someone in a double-role, then an "each" operator would need to be applied to the total list.

HTH
-- Mark
Relatives and Roles.json
Reply all
Reply to author
Forward
0 new messages