When writing modules, i am always struggling trying to identify the related dependencies of the functions, properties, etc...
That's why i am now trying to code using only pure functions, and to inject the dependencies when calling these functions instead of in the declaration, having the downside to may become quite verbose...
Could you tell me your thoughts about the pattern i used below (mainly regarding pure function declaration, and injecting dependencies when calling them)? Does it make sense, or is it more an overkill?
I am expecting answers containing "it depends", and i understand it. But i would like to implement some basic rules, stick to them and break them only if absolutely required.
// (... other code here...)
// DECLARATIONS: PURE FUNCTIONS
const randomInteger = (min, max) =>
Math.floor(Math.random() * (max - min + 1) + min)
const randomPosition = (useRandomInteger) => (min, max) => {
return [
useRandomInteger(min, max),
useRandomInteger(min, max)
]
}
const areEqualPositions = ([row1, col1], [row2, col2]) => row1 === row2 && col1 === col2
const uniquePosition = (useRandomPosition, useAreEqualPositions) => (min, max, excluded) => {
const pos = useRandomPosition(min, max)
return excluded.some(p => useAreEqualPositions(pos, p)) ?
uniquePosition(useRandomPosition, useAreEqualPositions)(min, max, excluded) :
pos
}
const generateRandomPositions = (useUniquePosition) => (n, {min, max}) => {
if(n > (max - min + 1) ** 2) throw new Error(`Invalid arguments...`)
return Array(n).fill(null)
.reduce(
(acc) => [...acc, useUniquePosition(min, max, acc)],
[]
)
}
// CALLING generateRandomPositions()... QUITE VERBOSE, BUT THE DEPENDENCIES ARE EASY TO UNDERSTAND... OVERKILL???
const randomPositions = generateRandomPositions(
uniquePosition(
randomPosition(
randomInteger
),
areEqualPositions
)
)
console.log(randomPositions(3, {min: 0, max: 2}))