1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
// Sorts a list of live, generic wiki data objects alphabetically.
// Note that this uses localeCompare but isn't specialized to a particular
// language; where localization is concerned (in content), a follow-up, locale-
// specific sort should be performed. But this function does serve to organize
// a list so same-name entries are beside each other.
import {input, templateCompositeFrom} from '#composite';
import {validateWikiData} from '#validators';
import {compareCaseLessSensitive, normalizeName} from '#wiki-data';
import {raiseOutputWithoutDependency} from '#composite/control-flow';
import {withMappedList, withSortedList, withPropertiesFromList}
from '#composite/data';
export default templateCompositeFrom({
annotation: `withThingsSortedAlphabetically`,
inputs: {
things: input({validate: validateWikiData}),
},
outputs: ['#sortedThings'],
steps: () => [
raiseOutputWithoutDependency({
dependency: input('things'),
mode: input.value('empty'),
output: input.value({'#sortedThings': []}),
}),
withPropertiesFromList({
list: input('things'),
properties: input.value(['name', 'directory']),
}).outputs({
'#list.name': '#names',
'#list.directory': '#directories',
}),
withMappedList({
list: '#names',
map: input.value(normalizeName),
}).outputs({
'#mappedList': '#normalizedNames',
}),
withSortedList({
list: '#normalizedNames',
sort: input.value(compareCaseLessSensitive),
}).outputs({
'#unstableSortIndices': '#normalizedNameSortIndices',
}),
withSortedList({
list: '#names',
sort: input.value(compareCaseLessSensitive),
}).outputs({
'#unstableSortIndices': '#nonNormalizedNameSortIndices',
}),
withSortedList({
list: '#directories',
sort: input.value(compareCaseLessSensitive),
}).outputs({
'#unstableSortIndices': '#directorySortIndices',
}),
// TODO: No primitive for the next two-three steps, yet...
{
dependencies: [input('things')],
compute: (continuation, {
[input('things')]: things,
}) => continuation({
['#combinedSortIndices']:
Array.from(
{length: things.length},
(_item, index) => index),
}),
},
{
dependencies: [
'#combinedSortIndices',
'#normalizedNameSortIndices',
'#nonNormalizedNameSortIndices',
'#directorySortIndices',
],
compute: (continuation, {
['#combinedSortIndices']: combined,
['#normalizedNameSortIndices']: normalized,
['#nonNormalizedNameSortIndices']: nonNormalized,
['#directorySortIndices']: directory,
}) => continuation({
['#combinedSortIndices']:
combined.sort((index1, index2) => {
if (normalized[index1] !== normalized[index2])
return normalized[index1] - normalized[index2];
if (nonNormalized[index1] !== nonNormalized[index2])
return nonNormalized[index1] - nonNormalized[index2];
if (directory[index1] !== directory[index2])
return directory[index1] - directory[index2];
return 0;
}),
}),
},
{
dependencies: [input('things'), '#combinedSortIndices'],
compute: (continuation, {
[input('things')]: things,
['#combinedSortIndices']: combined,
}) => continuation({
['#sortedThings']:
combined.map(index => things[index]),
}),
},
],
});
|