Reputation: 16501
I'm trying to functionally loop a list of numbers, checking each number against a list of rules to output an updated list consisting of numbers and strings. I'm having trouble understanding how I can combine the 2 loops without duplicating the number of items added (currently 1 * 3 iterations per number :/), I also get undefined
for all entries.
Can someone point me to the technique required to achieve this, the output should be [1, 2, 'In', 4, 'Out', 'In', 7, 8, 'In', 'Out', 11, 'In', 13, 14, 'InOut']
Code:
const range = (start, end) => Array.from({ length: end }, (_, i) => i + start)
const rules = [[3, 'In'], [5, 'Out'], [15, 'InOut']]
function output(range, markers) {
return range.map(num => {
markers.forEach(([div, text]) => {
if(num % div === 0) return text
return num
})
})
}
output(range(1, 10), rules)
Upvotes: 2
Views: 37
Reputation: 11592
You don't want to use forEach
, as that is for executing a function on each element of an array, like a map that doesn't return anything.
What you should do is look for the marker, and return the substitution if you find it.
That's what find
will do for you:
const range = (start, end) => Array.from({ length: end - (start-1) }, (_, i) => i + start)
const rules = [[15, 'InOut'], [5, 'Out'], [3, 'In']]
function output(range, markers) {
return range.map(num => {
let item = markers.find(marker => num % marker[0] === 0);
if(item){
return item[1];
}
return num;
})
}
console.log(output(range(1, 30), rules))
Also, order your rules by number of divisors, so prime numbers will be at the end. This is because find
takes the first hit, so you want it to find the numbers with the most divisors first.
Upvotes: 2