Search code examples
javascriptarraysstringvuejs2split

Split a string from numeric points and keep only the points' statements in a new array


I have this input-

"\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?"

I want this output-

[
  "What makes Vue a popular choice for web development?",
  "How does Vue compare to other JavaScript frameworks?",
  "What are the advantages of using Vue?",
  "Does Vue support server-side rendering?",
  "Is Vue compatible with TypeScript?",
  "Does Vue have a built-in router?",
]

I tried this-

let string = "\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?"

// First, remove all line breaks and two strings
string = string.replace(/(\r\n|\n|\r)/gm, "").replace('Open Ended Questions:', '').replace('Closed Ended Questions:', '');

// Split the string from this format, "<integer><dot><space>"
let result = string.split(/(\d+)\.\ /);

// Filter the only items which are not empty and not a number
result = result.filter(item => item && isNaN(item));

// Final result
console.log(result);

Code explanation-.

  1. Firstly, I removed all line breaks and some non-required strings.
  2. Secondly, I split the string from this format <integer><dot><space>, i.e. "1. ", "2. ", etc.
  3. At last, filtered only the numeric points' statements in a separate array.

The solution is working fine but I am not sure if its the right way to do this, because of this hardcoded removal operation- replace('Open Ended Questions:', '').replace('Closed Ended Questions:', '')

Can anyone please suggest a better/non-complex/correct way to do this?


Solution

  • Iterate the lines from the input and if a line matches /^\d+\.\s+ (that is, digits-dot-spaces), put the rest of the line in the array:

    input = "\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?"
    
    output = []
    
    for (let line of input.split('\n')) {
      line = line.trim()
      let m = line.match(/^\d+\.\s+(.+)/)
      if (m)
        output.push(m[1])
    }
    
    console.log(output)

    You can also do that with one single regular expression, but this would be less readable IMO:

    input = "\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?"
    
    output = [...input.matchAll(/^\d+\.\s+(.+)/gm)].map(r => r[1])
    
    console.log(output)