0

I am trying to find the best way to generate an array that has the following output:

[135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 275, 276, 277 , 278, 279, 280, 281, 282, 283, 284, 285, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 675, 676, 677, 678, 679, 700, 701, 702, 703, 704, 705 ...

As you can see it has a set of limits from 140 - 280 - 420 - 560 - 700 ( adds 148 to each value) and then there's an interval with minus 5 and plus 5 for each value.

I already tried this approach

scrollFrom =  Array.from(Array(bytesIndexTo).keys()).map(i => 140 + i * 140);

That returns me:

[140, 280, 420, 560, 700, ...

However I also need the plus and minus 5 values intervals...

I also noticed it uses to much resources.

        const prev = [
            [135,136,137,138,139],
            [275,276,277,278,279],
        ];

        const after = [
            [141,142,143,144,145],
            [281,282,283,284,285],
        ];

        for (let i = 0; i < scrollFrom.length; i++) {

            scrollFrom.push( scrollFrom[i] );

        }

The purpose of this array is to have a set of values that will help me to identify a certain scroll position in order to execute a function, the addition of this intervals will help me to figure the scroll position even if the user scrolls fast.

Maybe I could load the values inside a .json and load them ?

What do you think ? thanks in advance

4
  • Why do you have to generate the entire array if you're just trying to compare scroll positions? Wouldn't it be better to just see if it's within 5 of one of your sentinel positions? I don't understand why you have to pre-build all the possible values? Why not just calculate on the fly? Commented Mar 22, 2020 at 1:27
  • It uses the include function to check if the value is inside the array, and the array is quite big therefore a simple check won't work Commented Mar 22, 2020 at 2:07
  • I posted an answer that solves that problem a different way by just doing a quick calculation to see if a given number if within 5 of a multiple of 140. No pregenerated array needed. Commented Mar 22, 2020 at 2:34
  • FYI, these numbers in the array in your question 675, 676, 677, 678, 679 should be 695, 696, 697, 698, 699. Commented Mar 22, 2020 at 2:56

2 Answers 2

2

Once you create an array of central values (eg [140, 280, 420, 560, 700]), you can use flatMap to iterate over each item and construct another array of the 5 values below and above it:

const bytesIndexTo = 4;
const result = Array.from(
  { length: bytesIndexTo },
  (_, i) => (i + 1) * 140
)
  .flatMap(num => Array.from(
    { length: 11 },
    (_, j) => num - 5 + j
  ));
console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

1

So, if you all you really want to do is to be able to test if a number is within 5 of a sentinel multiple, then I don't think you really want to be generating a giant array and using .includes(). That would be slow. If you were going to pre-generate values, you should use a Set and then use .has() which should be a lot faster than .includes() for a large set of data.


But, it seems to be that you can just calculate a lot faster without doing any pre-generation at all.

In the code below, we divide by the multiple (140) and then look at the remainder. If the remainder is <=5 or >= 135, then it's within 5 of the multiple, otherwise not. It's really that simple. Since it appears you don't want the numbers 0-5 (around the zero multiple) to be counted as true, we add a special case for those.

// tests to see if a value is within 5 of a multiple of 140
const multiple = 140;
const over = 5;
const below = multiple - over;

function testValue(val) {
    if (val < below) return false;
    const delta = val % multiple;                // divide by multiple, get remainder
    return (delta <= over || delta >= below);  // see if remainder in right range
}

// run some tests on numbers at edges of the interval ranges
[
    0, 1, 
    134, 135, 140, 144, 145, 146,   // around 140
    274, 275, 280, 284, 285, 286,   // around 280
    414, 415, 420, 424, 425, 426,   // around 420
    554, 555, 560, 564, 565, 566    // around 560
].forEach(num => {
    console.log(`${num}: ${testValue(num)}`);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.