From 9230b40b39cc2ca33d73af1549e14c50b9617f1f Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Wed, 6 Mar 2024 14:25:16 -0400 Subject: data: withContributionListSums, withSum --- src/data/composite/data/index.js | 1 + src/data/composite/data/withSum.js | 33 +++++++ src/data/composite/wiki-data/index.js | 1 + .../wiki-data/withContributionListSums.js | 107 +++++++++++++++++++++ 4 files changed, 142 insertions(+) create mode 100644 src/data/composite/data/withSum.js create mode 100644 src/data/composite/wiki-data/withContributionListSums.js (limited to 'src/data') diff --git a/src/data/composite/data/index.js b/src/data/composite/data/index.js index 256c0490..0a47c43c 100644 --- a/src/data/composite/data/index.js +++ b/src/data/composite/data/index.js @@ -13,5 +13,6 @@ export {default as withPropertiesFromObject} from './withPropertiesFromObject.js export {default as withPropertyFromList} from './withPropertyFromList.js'; export {default as withPropertyFromObject} from './withPropertyFromObject.js'; export {default as withSortedList} from './withSortedList.js'; +export {default as withSum} from './withSum.js'; export {default as withUnflattenedList} from './withUnflattenedList.js'; export {default as withUniqueItemsOnly} from './withUniqueItemsOnly.js'; diff --git a/src/data/composite/data/withSum.js b/src/data/composite/data/withSum.js new file mode 100644 index 00000000..484e9906 --- /dev/null +++ b/src/data/composite/data/withSum.js @@ -0,0 +1,33 @@ +// Gets the numeric total of adding all the values in a list together. +// Values that are false, null, or undefined are skipped over. + +import {input, templateCompositeFrom} from '#composite'; +import {isNumber, sparseArrayOf} from '#validators'; + +export default templateCompositeFrom({ + annotation: `withSum`, + + inputs: { + values: input({ + validate: sparseArrayOf(isNumber), + }), + }, + + outputs: ['#sum'], + + steps: () => [ + { + dependencies: [input('values')], + compute: (continuation, { + [input('values')]: values, + }) => continuation({ + ['#sum']: + values + .filter(item => typeof item === 'number') + .reduce( + (accumulator, value) => accumulator + value, + 0), + }), + }, + ], +}); diff --git a/src/data/composite/wiki-data/index.js b/src/data/composite/wiki-data/index.js index a0a6be7f..9a9a5fa2 100644 --- a/src/data/composite/wiki-data/index.js +++ b/src/data/composite/wiki-data/index.js @@ -6,6 +6,7 @@ export {default as exitWithoutContribs} from './exitWithoutContribs.js'; export {default as inputWikiData} from './inputWikiData.js'; +export {default as withContributionListSums} from './withContributionListSums.js'; export {default as withDirectory} from './withDirectory.js'; export {default as withDirectoryFromName} from './withDirectoryFromName.js'; export {default as withParsedCommentaryEntries} from './withParsedCommentaryEntries.js'; diff --git a/src/data/composite/wiki-data/withContributionListSums.js b/src/data/composite/wiki-data/withContributionListSums.js new file mode 100644 index 00000000..cc37177e --- /dev/null +++ b/src/data/composite/wiki-data/withContributionListSums.js @@ -0,0 +1,107 @@ +// Gets the total duration and contribution count from a list of contributions, +// respecting their `countInContributionTotals` and `countInDurationTotals` +// flags. + +import {input, templateCompositeFrom} from '#composite'; + +import { + withFilteredList, + withPropertiesFromList, + withPropertyFromList, + withSum, + withUniqueItemsOnly, +} from '#composite/data'; + +export default templateCompositeFrom({ + annotation: `withContributionListSums`, + + inputs: { + list: input({type: 'array'}), + }, + + outputs: [ + '#contributionListCount', + '#contributionListDuration', + ], + + steps: () => [ + withPropertiesFromList({ + list: input('list'), + properties: input.value([ + 'countInContributionTotals', + 'countInDurationTotals', + ]), + }), + + withFilteredList({ + list: input('list'), + filter: '#list.countInContributionTotals', + }).outputs({ + '#filteredList': '#contributionsForCounting', + }), + + withFilteredList({ + list: input('list'), + filter: '#list.countInDurationTotals', + }).outputs({ + '#filteredList': '#contributionsForDuration', + }), + + { + dependencies: ['#contributionsForCounting'], + compute: (continuation, { + ['#contributionsForCounting']: contributionsForCounting, + }) => continuation({ + ['#count']: + contributionsForCounting.length, + }), + }, + + withPropertyFromList({ + list: '#contributionsForDuration', + property: input.value('thing'), + }), + + // Don't double-up the durations for a track where the artist has multiple + // contributions. + withUniqueItemsOnly({ + list: '#contributionsForDuration.thing', + }), + + withPropertyFromList({ + list: '#contributionsForDuration.thing', + property: input.value('duration'), + }).outputs({ + '#contributionsForDuration.thing.duration': '#durationValues', + }), + + { + dependencies: [ + input('list'), + '#contributionsForDuration.thing', + '#durationValues', + ], + compute: (continuation, opts) => { + console.log(opts); + return continuation(); + }, + }, + + withSum({ + values: '#durationValues', + }).outputs({ + '#sum': '#duration', + }), + + { + dependencies: ['#count', '#duration'], + compute: (continuation, { + ['#count']: count, + ['#duration']: duration, + }) => continuation({ + ['#contributionListCount']: count, + ['#contributionListDuration']: duration, + }), + }, + ], +}); -- cgit 1.3.0-6-gf8a5