I'm writing a script to print out some info scraped from a certain website, I'm using the .includes()
to find and print a number if that number falls inside a certain range from 1,000 to 100,000 but I can't figure out how to do that at all. The solution I'm trying right now is long and redundant and not even working.
Code
const numShare = await page.$$eval(".FormData", els =>
els.find(e => e.textContent.includes(',000' || ',9' || ',8' || ',7' || ',6' || ',5' || ',4' || ',3' || ',2' || ',1'))
.parentNode
.textContent
.trim()
);
return numShare;
One other thing I tried before is just using .includes(',000')
, which worked but it only gave me stricly numbers with a comma and 3 zeros after it. What I want is for it to find any number from 1,000 to 100,000 or with the format "x,xxx to xxx,xxx". Would this be possible?
CodePudding user response:
I can't see the page, HTML or text you're working with, but I guess you have numbers with commas delimiting thousands places. So why not simply remove those commas and parse the strings to numbers, then compare normally?
const numShare = await page.$$eval(".FormData", els =>
els.find(e => {
const n = e.textContent.trim().replace(/,/g, "");
return n >= 1000 && n <= 100000;
})
.parentNode
.textContent
.trim()
);
Runnable POC:
const els = [...document.querySelectorAll(".FormData")];
const result = els.find(e => {
const n = e.textContent.trim().replace(/,/g, "");
return n >= 1000 && n <= 100000;
})
.parentNode
.textContent
.trim();
console.log(result);
<div>
foo
<div >101,000</div>
</div>
<div>
baz
<div >1,000</div>
</div>
Another approach is const n = e.textContent.match(/\d/g).join("");
, which pulls out all of the numbers and is more tolerant of extra characters like currency symbols and spaces.
As for why your current approach doesn't work, you're just asking whether it includes the first truthy value in your giant ||
chain:
console.log(',000' || ',9' || ',8' || ',7' || ',6' || ',5' || ',4' || ',3' || ',2' || ',1');
CodePudding user response:
Unless I'm missing something, you should just be able to parse it into a number and check its value. However, this is a little more complicated if the input can have commas in it like your question suggests. I'm not entirely sure what you're trying to do with the surrounding code, but the parsing logic and checking logic should look something like this:
function isInRange(stringNum) {
const unformattedNum = stringNum.trim().split(", ").join("").split(",").join("");
// Or if you're ok with only supporting browsers from 2020 onwards...
// const unformattedNum = stringNumber.trim().replaceAll(", ", "").replaceAll("," , "");
const parsed = parseInt(unformattedNum); // Assuming these are always whole numbers, otherwise use parseFloat instead
return parsed >= 1000 && parsed <= 100000;
}
Then you could, for example, use that with the filter function to only get the items that are in range. e.g
const numbersInRange = numbers.filter(isInRange);
// (If you haven't used array.filter before, it removes any items where the provided function returns false for it)
But you'll probably want to split the parsing and checking into two separate functions, unless you only plan on changing the numbers while they're in string form.
So that's just:
function betterParse(stringNum) {
const unformattedNum = stringNum.trim().split(", ").join("").split(",").join("");
// Or if you're ok with only supporting browsers from 2020 onwards...
return parseInt(unformattedNum);
// ^ Assuming these are always whole numbers, otherwise use parseFloat instead
}
function isInRange(parsedNumber) {
return parsedNumber >= 1000 && parsedNumber <= 100000;
}
Hope this helps
Edit: added the trimming from ggorlen's answer. Thanks for the idea.
CodePudding user response:
Create a new array with the range of your values:
// helper
function range(start, end) {
return Array(end - start 1).fill().map((_, idx) => start idx)
}
let values = range(1000, 10000);