ddy250
ddy250

Reputation: 311

How to break a string into an array of objects

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.

Upvotes: 3

Views: 98

Answers (2)

Angelos Chalaris
Angelos Chalaris

Reputation: 6747

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);

Upvotes: 2

Mark
Mark

Reputation: 92440

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.

Upvotes: 2

Related Questions