3

I want to break this string:

data=

1.

Title: The Definitive Guide
Copy: There’s no way around it, 
URL: http://www.schools
Date: 6/7/17

2.

Title: Using 
Copy: Today’s fast
URL: https://blog
Date: 6/16/17
3.

Title: 4 Ways 
Copy: Let’s state
URL: https://www.
Date: 6/20/17

into an array of length=3 in this case (one for each of the numbering above). Each array item should be an object with the properties: title, copy, url, date.

I've tried this:

for(let i=0; i<3; i++) {

    arr[i] =temp.split(i+2 + ".");
    temp=temp.slice(0, arr[i].length);


};

Perhaps there is a simpler string method even. Could not find something similar looking in past questions published in SO.

3
  • What exactly does that string look like when you receive it? Commented Sep 13, 2018 at 15:26
  • There is no simple built-in method for parsing data from the format you've shown here. You can either write custom parsing code or get whoever's providing the input to conform to a more accepted standard (like JSON). Commented Sep 13, 2018 at 15:28
  • 1
    Please update the question to include a minimal reproducible example Commented Sep 13, 2018 at 15:34

2 Answers 2

2

I would opt for simply reading this line-by-line. Your lines will either be a number and a dot, empty space, or data. That's easy enough to loop through without getting involved in complex regexes:

data=`

1.

Title: The Definitive Guide
Copy: There’s no way around it, 
URL: http://www.schools
Date: 6/7/17

2.

Title: Using 
Copy: Today’s fast
URL: https://blog
Date: 6/16/17
31.

Title: 4 Ways 
Copy: Let’s state
URL: https://www.
Date: 6/20/17
`
let current, final = []
data.split('\n').forEach(line => {
  if (/^\d+\./.test(line)) final.push(current = {}) // new block
  else if (/\S/.test(line)){                        // some data
    let split = line.indexOf(":")
    let key = line.slice(0, split)
    let val = line.slice(split +1)
    current[key] = val.trim()
  }
})
console.log(final)

This assumes the data is clean. If there's a possibility of extraneous non-data lines, then you'll need to d a bit more work, but I think the basic idea would still work.

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

5 Comments

A lot more elegant and easier to understand than the solution I provided, honestly. I'd definitely prefer this.
The biggest assumption is that the data will be wrapped in a template literal. What happens if it's not that way and really is one long string?
@Chris I'm not really sure how a long string with line breaks would be different than this template literal -- it's still just a string. Can you clarify?
@MarkMeyer - If the data were like this: "1.Title: The Definitive Guide Copy: There’s no way around it, URL: schools Date: 6/7/17 2.Title: Using Copy: Today’s fast URL: blog Date: 6/16/17 3.Title: 4 Ways Copy: Let’s state URL: www Date: 6/20/17" -- your solution is looking for line breaks and there are no line breaks. Would your solution still be able to work through the data?
@Chris, no. This depends on data being on separate lines as it is in the OP. Whether it's a template literal as above or a string like \n1.\n\nTitle: The Definitive Guide\nCopy: There’s no way around it,, however, is not an issue.
2

This requires a lot of things to be done:

  • Split into lines
  • Filter out non-meaningful lines
  • Chunk in groups of 4
  • Create an object from each group

Here's my take on it, using chunk and objectFromPairs from 30secondsofcode (disclaimer: I am a maintainer of the project/website), as well as a multitude of Array methods:

var data = `

1.

Title: The Definitive Guide
Copy: There’s no way around it, 
URL: http://www.schools
Date: 6/7/17

2.

Title: Using 
Copy: Today’s fast
URL: https://blog
Date: 6/16/17
3.

Title: 4 Ways 
Copy: Let’s state
URL: https://www.
Date: 6/20/17
`;

const chunk = (arr, size) =>
  Array.from({
      length: Math.ceil(arr.length / size)
    }, (v, i) =>
    arr.slice(i * size, i * size + size)
  );

const objectFromPairs = arr => arr.reduce((a, [key, val]) => ((a[key] = val), a), {});


const dataArr = chunk(
  data.trim().split('\n')
  .filter(v => v.trim().indexOf(':') !== -1)
  .map(x => {
    let t = x.split(':');
    return [t[0], t.slice(1).join(':')].map(v => v.trim())
  }), 4
 ).map(o => objectFromPairs(o));
console.log(dataArr);

3 Comments

@OliverRadini fixed!
@AngelosChalaris - I don't think this really works, you get a four element array in the end, and the properties of the objects start getting off on the last couple of ones.
@Chris My bad, I was chunking 3 lines at a time, instead of 4.

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.