From d4e361e32e144d559b0a20c97025b7581dc4a1d5 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 17 Jun 2024 21:09:20 -0300 Subject: data: withIndexInList, withNearbyItemFromList --- src/data/composite/data/index.js | 2 + src/data/composite/data/withIndexInList.js | 38 ++++++++++++ src/data/composite/data/withNearbyItemFromList.js | 73 +++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 src/data/composite/data/withIndexInList.js create mode 100644 src/data/composite/data/withNearbyItemFromList.js (limited to 'src/data') diff --git a/src/data/composite/data/index.js b/src/data/composite/data/index.js index 0fc84061..c80bb350 100644 --- a/src/data/composite/data/index.js +++ b/src/data/composite/data/index.js @@ -25,6 +25,8 @@ export {default as withPropertiesFromList} from './withPropertiesFromList.js'; export {default as withFlattenedList} from './withFlattenedList.js'; export {default as withUnflattenedList} from './withUnflattenedList.js'; +export {default as withIndexInList} from './withIndexInList.js'; +export {default as withNearbyItemFromList} from './withNearbyItemFromList.js'; // Utilities which act on slightly more particular data forms // (probably, containers of particular kinds of values) diff --git a/src/data/composite/data/withIndexInList.js b/src/data/composite/data/withIndexInList.js new file mode 100644 index 00000000..b1af2033 --- /dev/null +++ b/src/data/composite/data/withIndexInList.js @@ -0,0 +1,38 @@ +// Gets the index of the provided item in the provided list. Note that this +// will output -1 if the item is not found, and this may be detected using +// any availability check with type: 'index'. If the list includes the item +// twice, the output index will be of the first match. +// +// Both the list and item must be provided. +// +// See also: +// - withNearbyItemFromList +// - exitWithoutDependency +// - raiseOutputWithoutDependency +// + +import {input, templateCompositeFrom} from '#composite'; + +export default templateCompositeFrom({ + annotation: `withIndexInList`, + + inputs: { + list: input({acceptsNull: false, type: 'array'}), + item: input({acceptsNull: false}), + }, + + outputs: ['#index'], + + steps: () => [ + { + dependencies: [input('list'), input('item')], + compute: (continuation, { + [input('list')]: list, + [input('item')]: item, + }) => continuation({ + ['#index']: + list.indexOf(item), + }), + }, + ], +}); diff --git a/src/data/composite/data/withNearbyItemFromList.js b/src/data/composite/data/withNearbyItemFromList.js new file mode 100644 index 00000000..83a8cc21 --- /dev/null +++ b/src/data/composite/data/withNearbyItemFromList.js @@ -0,0 +1,73 @@ +// Gets a nearby (typically adjacent) item in a list, meaning the item which is +// placed at a particular offset compared to the provided item. This is null if +// the provided list doesn't include the provided item at all, and also if the +// offset would read past either end of the list - except if configured: +// +// - If the 'wrap' input is provided (as true), the offset will loop around +// and continue from the opposing end. +// +// - If the 'valuePastEdge' input is provided, that value will be output +// instead of null. +// +// Both the list and item must be provided. +// +// See also: +// - withIndexInList +// + +import {input, templateCompositeFrom} from '#composite'; +import {atOffset} from '#sugar'; + +import {raiseOutputWithoutDependency} from '#composite/control-flow'; + +import withIndexInList from './withIndexInList.js'; + +export default templateCompositeFrom({ + annotation: `withNearbyItemFromList`, + + inputs: { + list: input({acceptsNull: false, type: 'array'}), + item: input({acceptsNull: false}), + + offset: input({type: 'number'}), + wrap: input({type: 'boolean', defaultValue: false}), + }, + + outputs: ['#nearbyItem'], + + steps: () => [ + withIndexInList({ + list: input('list'), + item: input('item'), + }), + + raiseOutputWithoutDependency({ + dependency: '#index', + mode: input.value('index'), + + output: input.value({ + ['#nearbyItem']: + null, + }), + }), + + { + dependencies: [ + input('list'), + input('offset'), + input('wrap'), + '#index', + ], + + compute: (continuation, { + [input('list')]: list, + [input('offset')]: offset, + [input('wrap')]: wrap, + ['#index']: index, + }) => continuation({ + ['#nearbyItem']: + atOffset(list, index, offset, {wrap}), + }), + }, + ], +}); -- cgit 1.3.0-6-gf8a5