I am searching for a simpler approach to combine a dictionary and a list into a single list using functional programming. Here is an example of the dictionary, list, and expected outcome:
const myDictionary = new Map<string, number>([
['a', 4],
['b', 0],
['c', 3]
])
const myList = [
'a',
'b',
'c'
]
const expectedResult = [
[
{'index': 0, 'payload': 'a0'},
{'index': 1, 'payload': 'a1'},
{'index': 2, 'payload': 'a2'},
{'index': 3, 'payload': 'a3'}
],
[],
[
{'index': 4, 'payload': 'c0'},
{'index': 5, 'payload': 'c1'},
{'index': 6, 'payload': 'c2'}
]
]
The number of items in the inner list of expectedResult
varies. In this instance, it corresponds to the values in the map myDictionary
, but this can vary. The function for generating these inner list items is deterministic, but the values need to be computed, matched, or combined.
My query is how can I accomplish this in a functional manner. I could attempt something like this (using Randa library):
Define a function to transform each list item:
const transformListItem = (char: string, offset: number, dictionary: Map<string, number>) =>
range(0, dictionary.get(char)).map(i => ({
'index': i + offset,
'payload': `${char}${i}`
}))
Here is how it would be implemented:
const transformList = (list: string[], dictionary: Map<string, number>) =>
list.map((char, listItemIndex) => {
const listPriorToThisItem = slice(0, listItemIndex, list)
const transformedListPriorThisItem = transformList(listPriorToThisItem, dictionary)
const indexOffset = sum(transformedListPriorThisItem.map(a => a.length))
return transformListItem(char, indexOffset, dictionary)
}
const result = transformList(myList, myDictionary)
However, this approach involves redundant calculations for each list item. So, my question is: Is there a way to avoid repeating this calculation multiple times? Memoization is an option, but it adds complexity. A non-functional solution would involve iterating an index variable:
const transformList = (list: string[], dictionary: Map<string, number>) => {
let indexOffset = 0
return list.map(char => {
const transformedItem = transformListItem(char, indexOffset, dictionary)
indexOffset += transformedItem.length
return transformedItem
}
}
const result = transformList(myList, myDictionary)
Are there any more direct patterns in functional programming to achieve this?