简体   繁体   中英

How to loop in javascript until condition is met and add the results to an array?

I need to push two key/value pairs to an array based on the different conditions.

Condition for the first key/value : only paragraph starting with the number.

Condition for the second key/value : all paragraphs after the first key/value pair (until the next paragraph starting with number).

Here is the html example:

<div class="someclass">
    <p><strong>1. Some text</strong></p>
    <p>Some text related to 1.</p>
    <p>Some other <a href="/someurl"><strong> text</strong></a> related to 1.</p>
    <p><strong>2. Some other text</strong></p>
    <p>Some text related to 2.</p>
    <p><strong>3. Can you send me a catalog?</strong></p>
    ...
</div>

I am able to get only one paragraph for the second key/value pair with this javascript code:

var array = [];
var allParagraphs = document.querySelectorAll("someclass p");
for (i = 0; i < allParagraphs.length; i++) {
    if (/^\d/.test(allParagraphs[i].innerText) === true) {
        array.push({
            "key1": allParagraphs[i].innerText,
            "customText": {
                "key2": allParagraphs[i + 1].innerText
            }
        });
    }
}

The output I get is something like:

[{key1: "1. Some text", customText: {key2: "Some text related to 1."}},{key1: "2. Some text", customText: {key2: "Some text related to 2."}},{...}]

And I need to get something like this:

[{key1: "1. Some text", customText: {key2: "Some text related to 1. Some other text related to 1."}},{key1: "2. Some text", customText: {key2: "Some text related to 2."}},{...}]

Does this work for you?

You can filter out empty key2 if you need

 const vals = [...document.querySelectorAll(".someclass p")].reduce((acc, elem) => { const first = elem.firstChild; if (first.tagName === "STRONG" && first.textContent.match(/^\d+\./)) { acc.push({ "key1": elem.textContent, "customtext": { "key2": [""] } }) } else acc[acc.length - 1].customtext.key2[0] += elem.textContent; return acc }, []) console.log(vals)
 <div class="someclass"> <p><strong>1. Some text</strong></p> <p>Some text related to 1.</p> <p>Some other <a href="/someurl"><strong> text</strong></a> related to 1.</p> <p><strong>2. Some other text</strong></p> <p>Some text related to 2.</p> <p><strong>3. Can you send me a catalog?</strong></p> </div>

ES5

 const elems = document.querySelectorAll(".someclass p"); const acc = []; for (let i=0;i<elems.length;i++) { const first = elems[i].firstChild; if (first.tagName === "STRONG" && first.textContent.match(/^\d+\./)) { acc.push({ "key1": elems[i].textContent, "customtext": { "key2": [""] } }) } else acc[acc.length - 1].customtext.key2[0] += elems[i].textContent; } console.log(acc)
 <div class="someclass"> <p><strong>1. Some text</strong></p> <p>Some text related to 1.</p> <p>Some other <a href="/someurl"><strong> text</strong></a> related to 1.</p> <p><strong>2. Some other text</strong></p> <p>Some text related to 2.</p> <p><strong>3. Can you send me a catalog?</strong></p> </div>

I think the problem is that this:

for (i = 0; i < allParagraphs.length; i++) {
    if (/^\d/.test(allParagraphs[i].innerText) === true) {

Should be this:

for (i = 0; i < allParagraphs.length; i++) {
    while (/^\d/.test(allParagraphs[i].innerText) === true) {

Basically, the IF statement runs once and then proceeds to the next for loop, while the WHILE is running while the condition inthe parentheses is true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM