I'm learning ramda by rewriting a function we have that parses numbers inside parenthesis in an array of strings. When I write this as a single compose function, both commented filter and map lines throw an error:
Cannot read properties of undefined (reading 'fantasy-land/filter')
Yet when I write them as two different compose functions, they work fine.
The match/nth compose returns [ '123', '456', '789' ]
When I debug, it looks like R.filter and R.map are operating on the individual characters of the strings instead of each element that R.nth is returning.
[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
Not working:
const extractNumbersInParenthesesFilterAndConvert = R.compose(
R.map(Number), // errors
R.filter(Boolean), // errors
R.nth(1),
R.match(/\((\d+)\)$/)
);
// Function to process an array of strings and return the extracted numbers
const extractNumbersFromStrings = R.map(extractNumbersInParenthesesFilterAndConvert);
const inputArray = [
'Some text (123)',
'Another string (456)',
'No numbers here',
'Last string (789)',
];
let result = extractNumbersFromStrings(inputArray);
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.29.0/ramda.js"></script>
Working:
const extractNumbersInParentheses = R.compose(
// R.map(Number), // errors
// R.filter(Boolean), // errors
R.nth(1),
R.match(/\((\d+)\)$/)
);
const filterAndConvert = R.compose(
R.map(Number),
R.filter(Boolean)
);
// Function to process an array of strings and return the extracted numbers
const extractNumbersFromStrings = R.map(extractNumbersInParentheses);
const inputArray = [
'Some text (123)',
'Another string (456)',
'No numbers here',
'Last string (789)',
];
let result = extractNumbersFromStrings(inputArray);
result = filterAndConvert(result)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.29.0/ramda.js"></script>
The issue is that the
R.match/R.nthfunctions are being run viaR.mapon each string in the array, butR.filter/R.mapare meant to run on the results of that map, yet are inside the compose so they're running on the result of each individual string regex/nth.Throwing an
R.tapin there to debug confirms:It works as two composes because one operates on each string while the second operates on the results. Knowing this, it can be rewritten a variety of ways. Here's one: