“This is the 24th day of my participation in the First Challenge 2022. For details: First Challenge 2022”


This article brings about the application of FP functional programming idea in JS [loop].

The more I understand you guys, the better you guys will be

In general, write a loop:

for (let i=9; i<=22; i++) {

    // do something with i

}
Copy the code

Or:

let i = 9;
while (i <= 22) {
    // do something with i
    i++;
}
Copy the code

What’s wrong with writing this?

Yes, there are QAQ

  • Prone to marginal problems — also known as the “off-by-one” Bug. For example, missing the < sign;

  • If index I changes, the loop will cause an error (why is I prone to change? Because for loops, such as while, the index I is an external variable, and changes to the external variable are not controlled inside the loop;)

  • The code is too long, and the loop structure may be longer than the functional code of the operation;

Therefore, we try to use FP functional programming ideas to do the transformation of the cycle ~

The expectation after the transformation is something like this:

range(9, 22).forEach(i => {
    /* do something with i */
})
Copy the code

Range function implementation:

const range = (from, to) => {
    const arr = [];
    do {
    arr.push(from);
    from++;
    } while (to >= from);
    return arr;
};
Copy the code

Range (9,22) expansion is [9, 10, 11… 22], if you want to reverse the array, for example, range(12,11,10…4) expansion is [12,11,10…4]

const range = (from, to, step = Math.sign(to - from)) => { const arr = []; do { arr.push(from); from += step; } while ((step > 0 && to >= from) || (step < 0 && to <= from)); return arr; }; Range (12, 4)Copy the code

So we have a simple encapsulation!

There’s one more problem — the way it’s written right now, the loop is out of control. That is, we can’t stop or break the loop at will;

To solve this problem, try.some(fn) instead of.foreach (fn);

  • some() Method tests whether at least 1 element in the array passes the provided function test. It returns a Boolean value.

e.g.

function isBiggerThan10(element, index, array) {
  return element > 10;
}

[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true
Copy the code

As long as the Fn function returns false, the loop continues; When it returns true, the loop ends.

Generators will return a value each time it is called.

The range() function evolves as follows:

function* range(from, to, step = Math.sign(to - from)) {
    do {
        yield from;
        from += step;
    } while ((step > 0 && to >= from) || (step < 0 && to <= from));
}
Copy the code
for (const i of range(9, 22)) { i => { ... . if (someCondition) continue; . if (somethingElse) break; . . } // Assign an array const arrayFrom9To22 = [...range(9, 22)]; // this produces [9, 10, 11, ... 22]Copy the code

In this way, you can even assign an array range(9,999999999999) without exploding memory because it is generated by generators and is inert; MDN- iterator has a description:

The most common iterator in Javascript is the Array iterator, which simply returns each value in the associative Array in order. While it’s easy to imagine that all iterators can be represented as arrays, this is not the case. Arrays must be fully allocated, but iterators are used only when necessary, so sequences of infinite sizes can be represented, such as the integer range between 0 and infinity.

Summary: through THE FP functional programming thinking of “loop” for a simple package, making the code readability and scalability are enhanced some, pin not stamp 👍

  • Functional-ranges -for-loops- Generating – Better -loops

OK, that’s it

I’m Nuggets Anthony, output exposure input, technical insight into life, goodbye ~~