TiddlyWiki5 icon indicating copy to clipboard operation
TiddlyWiki5 copied to clipboard

[IDEA] Filter operator `interleave` that merges two (or more) lists together

Open rmunn opened this issue 2 years ago • 3 comments

Is your feature request related to a problem? Please describe. I recently wanted to be able to merge two lists together "zipper-style", e.g. taking A B C and 1 2 3 and producing A 1 B 2 C 3.

Describe the solution you'd like I'd like a list operator named interleave, or possibly zip but that's a name that won't be obvious to non-programmers, that would interleave two or more lists together. Its first input list would be the results of the filter expression so far, and any parameters given to interleave would be treated as title lists the same way the enlist operator treats its operands.

E.g., to get the A 1 B 2 C 3 result I mentioned, you'd write A B C +[interleave[1 2 3]]. Or have 1 2 3 saved in a variable (probably as the result of a previous filter expression) and do A B C +[interleave<previous-result>].

interleave would also be able to take multiple parameters, and would treat them in round-robin fashion, taking one input from each list in turn. So [interleave[A B C],[1 2 3],[red green blue]] would produce A 1 red B 2 green C 3 blue.

If one or more input lists run out of items, interleave just stops taking from those lists and continues taking from the rest of its input until all input lists are exhausted. So A B C D +[interleave[1 2]] would produce A 1 B 2 C D. And [interleave[1 2 3]] (where the input list is empty) would basically be synonymous with the enlist operator.

Describe alternatives you've considered It might be possible to do something clever with the cycle operator to achieve this result, but that seems like overkill.

It might be possible to expand the enlist operator to take multiple parameters, but I feel like that won't be as discoverable as creating a new operator with a more specific name.

rmunn avatar Aug 09 '22 02:08 rmunn

One design question that needs addressing: should interleave de-duplicate its output using dominant append, or leave any duplicates untouched? I'm inclined to say that it should de-duplicate by default, so that it works like other list operations, and that suffixes should be used similar to how enlist works. But a case could be made that when you interleave two lists, you're going to expect the values from both lists to all appear in the result even if they contained duplicates, so it's possible that dedupe should be the default.

Also, what should the suffix be named? When I wrote #6896 I just copied the raw and dedupe names from the enlist operator, but it's possible I should call it allowdupes instead of raw. If someone has a better suggestion than raw, I'd be interested in hearing it.

rmunn avatar Aug 11 '22 04:08 rmunn

I'm not sure, what interleave returns. So if I feed it: a b c +[interleave[1 2 3]] Does is return 3 titles or 6 titles. If the answer is 6 then it should do "dedupe" as default. Same as other lists.

pmario avatar Aug 11 '22 07:08 pmario

I'd like a list operator named interleave, or possibly zip but that's a name that won't be obvious to non-programmers

I would vote for zip! It is known in some other languages like Python

kookma avatar Aug 11 '22 13:08 kookma

@rmunn interesting ideas, I personally cant think of a reason for interleave but I am very interested in any ways we can use to manipulate sets and perhaps even one day multidimensional arrays.

However have you considered seeing if you can leverage the setmultiple-variables widget? Or any operator with $name $values parameters/filters. in some ways this "interleaves the name and the value". If you use the $parameters widget you can access a JSON array of key/value pairs, and you could change the value to include the interleaved set. You may even be able to store the result in the way it is reversible, to split the sets or opposite to interleave, "unzip", but yes we need better words but perhaps you could qualify it to avoid ambiguity eg word-zip and word-unzip, or token-zip, title-zip etc...

  • I suspect we need to assume both sets are of equal length sometimes, but not others?

This only theoretical for the moment but it seems possible to me. Another talk.tiddlywiki thread also has a recursive function using two functions written by @saqimtiaz which to me suggests the ability exists already it is just working out how to.

I became adept at the balance line algorithm in the mainframe world last millennium, a version of which could simply interleave but also do so with sophisticated partial rearrangements.

Perhaps looking at what set (read list or titles) manipulations are available to tiddlywiki, identify the gaps and create some operators for them so we gain a complete set would be a useful strategy.

What you want sounds like;

Cartesian Product: The Cartesian product of two sets A and B is a set of all possible ordered pairs where the first element is from A and the second is from B. It's denoted as A×B.

[Cartesian.Product<setA>,<setB>]

AnthonyMuscio avatar Nov 13 '23 13:11 AnthonyMuscio