From 0237d9ed948367c4d95717c0debe2c0af9c0a6b2 Mon Sep 17 00:00:00 2001 From: Saq Imtiaz Date: Thu, 21 Jul 2022 10:23:01 +0200 Subject: [PATCH] feat(filters): extend :map filter run prefix to accept a suffix to enable mapflat (#6806) --- core/modules/filterrunprefixes/map.js | 12 ++++++++++-- editions/test/tiddlers/tests/test-prefixes-filter.js | 2 ++ .../syntax/Map Filter Run Prefix (Examples).tid | 7 ++++++- .../filters/syntax/Map Filter Run Prefix.tid | 5 +++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/core/modules/filterrunprefixes/map.js b/core/modules/filterrunprefixes/map.js index 632b160e7..efcb5b534 100644 --- a/core/modules/filterrunprefixes/map.js +++ b/core/modules/filterrunprefixes/map.js @@ -16,7 +16,9 @@ exports.map = function(operationSubFunction,options) { return function(results,source,widget) { if(results.length > 0) { var inputTitles = results.toArray(), - index = 0; + index = 0, + suffixes = options.suffixes, + flatten = (suffixes[0] && suffixes[0][0] === "flat") ? true : false; results.clear(); $tw.utils.each(inputTitles,function(title) { var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{ @@ -36,7 +38,13 @@ exports.map = function(operationSubFunction,options) { } } }); - results.push(filtered[0] || ""); + if(filtered.length && flatten) { + $tw.utils.each(filtered,function(value) { + results.push(value); + }) + } else { + results.push(filtered[0]||""); + } ++index; }); } diff --git a/editions/test/tiddlers/tests/test-prefixes-filter.js b/editions/test/tiddlers/tests/test-prefixes-filter.js index f6f71328f..e32827f9f 100644 --- a/editions/test/tiddlers/tests/test-prefixes-filter.js +++ b/editions/test/tiddlers/tests/test-prefixes-filter.js @@ -416,6 +416,8 @@ describe("'reduce' and 'intersection' filter prefix tests", function() { expect(wiki.filterTiddlers("[tag[shopping]] :map[get[description]else{!!title}]").join(",")).toBe("A square of rich chocolate cake,a round yellow seed,Milk,Rice Pudding"); // Return the first title from :map if the filter returns more than one result expect(wiki.filterTiddlers("[tag[shopping]] :map[tags[]]").join(",")).toBe("shopping,shopping,shopping,shopping"); + // Return all titles from :map if the flat suffix is used + expect(wiki.filterTiddlers("[tag[shopping]] :map:flat[tags[]]").join(",")).toBe("shopping,food,shopping,food,shopping,dairy,drinks,shopping,dairy"); // Prepend the position in the list using the index and length variables expect(wiki.filterTiddlers("[tag[shopping]] :map[get[title]addprefix[-]addprefixaddprefix[of]addprefix]").join(",")).toBe("0of4-Brownies,1of4-Chick Peas,2of4-Milk,3of4-Rice Pudding"); }); diff --git a/editions/tw5.com/tiddlers/filters/syntax/Map Filter Run Prefix (Examples).tid b/editions/tw5.com/tiddlers/filters/syntax/Map Filter Run Prefix (Examples).tid index 008e5d0c5..5c9107af2 100644 --- a/editions/tw5.com/tiddlers/filters/syntax/Map Filter Run Prefix (Examples).tid +++ b/editions/tw5.com/tiddlers/filters/syntax/Map Filter Run Prefix (Examples).tid @@ -1,5 +1,5 @@ created: 20210618134753828 -modified: 20211125152755859 +modified: 20220720191457421 tags: [[Filter Syntax]] [[Filter Run Prefix Examples]] [[Map Filter Run Prefix]] title: Map Filter Run Prefix (Examples) type: text/vnd.tiddlywiki @@ -15,6 +15,11 @@ For each title in a shopping list, calculate the total cost of purchasing each i <<.operator-example 2 "[tag[shopping]] :map[get[quantity]else[0]multiply{!!price}]">> +Get the tags of all tiddlers tagged `Widget:` + +<<.operator-example 3 "[tag[Widgets]] :map:flat[tagging[]] :and[!is[blank]unique[]]">> +<<.tip "Without the `flat` suffix the `:map` filter run only returns the first result for each input title">> + !! Comparison between `:map` and `:and`/`+` filter run prefixes The functionality of the `:map` filter run prefix has some overlap with the `:and` prefix (alias `+`). They will sometimes return the same results as each other. In at least these cases, the results will be different: diff --git a/editions/tw5.com/tiddlers/filters/syntax/Map Filter Run Prefix.tid b/editions/tw5.com/tiddlers/filters/syntax/Map Filter Run Prefix.tid index 30282e1ca..ad36fcade 100644 --- a/editions/tw5.com/tiddlers/filters/syntax/Map Filter Run Prefix.tid +++ b/editions/tw5.com/tiddlers/filters/syntax/Map Filter Run Prefix.tid @@ -1,5 +1,5 @@ created: 20210618133745003 -modified: 20211029025541750 +modified: 20220720190146771 tags: [[Filter Syntax]] [[Filter Run Prefix]] title: Map Filter Run Prefix type: text/vnd.tiddlywiki @@ -8,6 +8,7 @@ type: text/vnd.tiddlywiki |''purpose'' |modify input titles by the result of evaluating this filter run for each item | |''input'' |all titles from previous filter runs | +|''suffix''|<<.from-version "5.2.3">> `flat` to return all results from the filter run, If omitted (default), only the first result is returned.| |''output''|the input titles as modified by the result of this filter run | Each input title from previous runs is passed to this run in turn. The filter run transforms the input titles and the output of this run replaces the input title. For example, the filter run `[get[caption]else{!!title}]` replaces each input title with its caption field, unless the field does not exist in which case the title is preserved. @@ -22,6 +23,6 @@ The following variables are available within the filter run: * ''revIndex'' - <<.from-version "5.2.1">> the reverse numeric index of the current list item (with zero being the last item in the list). * ''length'' - <<.from-version "5.2.1">> the total length of the input list. -Filter runs used with the `:map` prefix should return the same number of items that they are passed. Any missing entries will be treated as an empty string. In particular, when retrieving the value of a field with the [[get Operator]] it is helpful to guard against a missing field value using the [[else Operator]]. For example `[get[myfield]else[default-value]...`. +Filter runs used with the `:map` prefix should return at least the same number of items that they are passed. Any missing entries will be treated as an empty string. In particular, when retrieving the value of a field with the [[get Operator]] it is helpful to guard against a missing field value using the [[else Operator]]. For example `[get[myfield]else[default-value]...`. [[Examples|Map Filter Run Prefix (Examples)]] \ No newline at end of file