1

In Javascript, I have a string that I need to convert to an Array of objects.

//ORIGINAL STRING :
var originalString = "[13, "2017-05-22 17:02:56", "Text111"], [25, "2017-05-22 17:03:03", "Text222"], [89, "2017-05-22 17:03:14","Text333"]";

I need to be able to loop through each object, and get the 3 properties by using indexes. That would give (for the first Array) :

myItem[0] => 13
myItem[1] => "2017-05-22 17:02:56"
myItem[2] => "Text111"

That first sounded simple to my head (and probably is), but after several attempts, I am still stuck.

Please note that I cannot use jQuery because running with a very old Javascript specification : "Microsoft JScript", which is EcmaScript 3 compliant.

I thank you ;)

5
  • Your originalString code will throw errors due to invalid JS syntax. Are you missing quote escaping? Commented May 25, 2017 at 3:29
  • 1
    You could always eval it. Why are you using such an old version anyway? If you updated to at least 5.1 then you could use JSON.parse. Commented May 25, 2017 at 3:31
  • @Yeldar Kurmangaliev : Yes, the originalString contains ", and this is not correct. The fact is that this string is returned AS IS by an external API (such a shame). @Andrew Li : I CAN use JSON.parse (I have implemented a JS port of it, and it is fully functional). Commented May 25, 2017 at 3:38
  • Why would you implement JSON.parse() yourself rather than including the original json2.js that Mr Crockford implemented years ago? Commented May 25, 2017 at 3:56
  • @nnnnnn The port of JSON.parse I am talking about IS the one by Crockford ;-) (json2.js) Commented May 25, 2017 at 4:14

2 Answers 2

1

If you just could use JSON.parse, then you would be able to append [ and ] to the beginning and ending of a string respectively, and then parse it as an array of arrays.

var originalString = '[13, "2017-05-22 17:02:56", "Text111"], [25, "2017-05-22 17:03:03", "Text222"], [89, "2017-05-22 17:03:14","Text333"]';

var result = JSON.parse("[" + originalString + "]");
console.log(result);

However, as far as I know, JSON.parse is not ECMAScript 3 complaint, so you will have to parse it yourself.
Something like this should help:

var originalString = '[13, "2017-05-22 17:02:56", "Text111"], [25, "2017-05-22 17:03:03", "Text222"], [89, "2017-05-22 17:03:14","Text333"]';

function trimString(str, trims) {
  var left = 0;
  var right = str.length - 1;
  
  while (left < right && trims.indexOf(str[left]) != -1) {
    left++;
  }
   
  while (left < right && trims.indexOf(str[right]) != -1) { 
    right--;
  }
  
  return str.substr(left, right - left + 1);
}

function splitByCommasOutOfBrackets(str) {
  var result = [];
  var current = "";
  var bracketBalance = 0;
  
  for (var i = 0; i < str.length; i++)
  {
    switch (str[i]) {
      case '[':
        current = current + str[i];
        bracketBalance++;
        break;
        
      case ']':
        current = current + str[i];
        bracketBalance--;
        break; 
        
      case ',':
        if (bracketBalance === 0) {
          result.push(trimString(current, [" ", "[", "]", "\""]));
          current = "";
        } else {
          current = current + str[i];
        }
        break;  
        
      default:
        current = current + str[i];
        break;
    }
  }
  
  if (current.length > 0) {
    result.push(trimString(current, [" ", "[", "]", "\""]));
  }
  
  return result;
}

var arr = splitByCommasOutOfBrackets(originalString);
console.log("1: Split by commas which separate arrays");
console.log(arr);

for (var i = 0; i < arr.length; i++) {
  arr[i] = splitByCommasOutOfBrackets(arr[i]);
}

console.log("2: Split every array by the same rules");
console.log(arr);

I am not quite sure what functionality exists in ECMAScript 3 and I used MDN for this. It looks like many functions even like String.prototype.trim do not exist in ECMAScript 3. So I had to reimplement it myself. If I am wrong and you can use them in JScript, then just use some of these functions instead.

The general idea of algorithm is the following:

  1. Split string by commas out of brackets, i.e. commas which separate our arrays. And then trim each string whitespaces, brackets, quotes - all these things that we don't need. As the result, we have an array of strings, each of them represents an array.
  2. Then apply the same rule for every array, separating it to values.

Note that all values are threaded as strings in this solution.

It could be rewritten in a recursive way instead of looping if you have more nested levels, but it would be less understandable - I just have provided a minimal solution which works :) I am sure you can improve it in many ways.

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

2 Comments

Thank you for this great base ! I went with a similar approach, but not pushed as much as you did. Dealing with the start and end of lines is a difficult part, I know...especially with the variants of [", with sometimes many spaces before and after..
This works with only your first block of code, beacause JSON.parse() is implemented with the use of the Crockford library (github.com/douglascrockford/JSON-js). Thank you !
1

Something like this should do

var regex = /\[([^\]]+)/g;
var originalString = '[13, "2017-05-22 17:02:56", "Text111"], [25, "2017-05-22 17:03:03", "Text222"], [89, "2017-05-22 17:03:14","Text333"]';
var result = regex.exec(originalString);
var container = [];
for (var j = 0; result ? true : false; j++) {
  var tokens= result[1].split(',');
  var tempContainer = []
  for (var i = 0; i < tokens.length; i++) {
    tempContainer[i] = tokens[i].replace(/["\s]/g, '');
  }
  container[j] = tempContainer;
  // continue the search
  result = regex.exec(originalString);
}
console.log(container);

2 Comments

This solution is BRILLIANT ! But infortunately, EcmaScript 3 does not support the .push() method neither the .trim() method :(
Thank you for your edit ! I have marked Yeldar Kurmangaliyev as the best answer because it is the sortest, but I gave you an Upvote for the Regex approach I really like ! Thank you Dummy

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.