Mr. Jo
Mr. Jo

Reputation: 5251

How can I convert a string which contains an Array of Objects back to an Array?

I'm receiving a stringified Array of Objects in JS:

"[{version:07/18,test:true}]"

How can I get this back to an Array I can work with in JS? I've tried JSON.parse but this don't worked:

var abc = "[{version:07/18,test:true}]";

console.log(JSON.parse(abc));

Thanks for helping me!

Upvotes: 0

Views: 131

Answers (3)

Paul
Paul

Reputation: 141829

If you can't fix the source you aren't left with any great options. You could use a library such as relaxed-json to parse JSON with missing quotes on keys, but it doesn't handle the 07/18 so you will need to quote that first.

const str = "[{version:07/18,test:true}]";

// Quote strings in the format 07/18:
const quoted = str.replace( /\d+\/\d+/g, '"$&"' );

// Parse with relaxed-json
const result = RJSON.parse( quoted );

console.log( result[0].version );
console.log( result );
<script src="https://cdn.jsdelivr.net/npm/[email protected]/relaxed-json.min.js"></script>

This is fragile code, that might work now for what you need, but will stop working if the source ever includes any other weird values that don't match the \d+/\d+ pattern. I recommend that if you use something along these lines, you treat it as a temporary solution, and keep putting pressure on the maintainer of the data source to return their data as JSON.

Upvotes: 1

ThS
ThS

Reputation: 4783

As the stringified Array of Objects you have isn't a valid JSON string, the JSON.* functions can't deal with it.

A solution is to create your own parser that deals with the type of strings you have and returns an array of objects created from those in the string.

I created a one for you :

/**
* a function designed to parse strings like the one you have
* it can deal with multiple objects in that string.
* @param arrLikeStr a string that as the one you have. Begins with "[" and ends with "]" and as much objects enclosed in "{" and "}" and separated with ",".
**/
const populateArrray = arrLikeStr => {
  /** remove "[", "]" and spaces **/
  arrLikeStr = arrLikeStr.replace(/[\[\]\s]/g, '');
  /** split the string based on '},' to get the objects in that string and loop through them **/
  return arrLikeStr.split('},').map(item => {
    /** represents the current object (item) that is parsed **/
    const obj = {};
    /** remove "{" and "}" from the current item **/
    /** split it based on "," and loop through **/
    item.replace(/[{}]/g, '').split(',').forEach(key => {
     /** split based on ":" to get the objects's attributes **/
      key = key.split(':');
      /** construct the object **/
      /** "true" and "false" are represented as boolean true and false **/
      obj[key[0]] = ['true', 'false'].indexOf(key[1]) !== -1 ? Boolean(key[1]) : key[1];
    });
    /** return the object after constructing it **/
    return obj;
  });
};

/** tests **/

const str = "[{version:07/18,test:true},{version:17/03,test:false}]",
  arr = populateArrray(str);

/** print the whole parsed array **/
console.log(arr);

/** print the second object in the parsed array **/
console.log('second object:');
console.log(arr[1]);

/** print the version of the first object in the parsed array **/
console.log('first object version:');
console.log(arr[0].version);
.as-console-wrapper {
  min-height: 100%;
}

Upvotes: 1

27mdmo7sn
27mdmo7sn

Reputation: 509

hope this approach works with you

replace each , by },{ then convert the string into array using split method (",")

// original string : "[{version:07/18,test:true}]"

var arr;
abc = abc.replace("," , "},{"); // "[{version:07/18},{test:true}]"
arr = abc.split(","); // [{version:07/18},{test:true}]

then you can parse each element in the array alone

JSON.parse(arr[0]); // {version:07/18}
JSON.parse(arr[1]); // {test:true}

Upvotes: 0

Related Questions