Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String split to javascript Object

I have string coming from the server:

//A
123|155-244
  • The first numbers always means 'Red'
  • Numbers after | always means 'Green'
  • Numbers after -always means 'Blue'

The issue here is that Green and Blue can come back in either order:

//B
123-244|155

Or they can be missing entirely:

//C
123|155 

I need a function that returns one array/object to make things easy:

//A
var result = {red:"123", green:"155", blue:"244"}

//B
var result = {red:"123", green:"155", blue:"244"}

//C
var result = {red:"123", green:"155", blue:"0"}

I've tried two functions, one to get Green and the other Blue, but I realized that doesn't work properly depending on the order they appear in the string.

var getGreen = function(myvar){
    return myvar.split('-'); 
};
var getBlue = function(myvar){
    return myvar.split('|'); 
};

Doing this sometimes causes my object to look like this:

var result = {red:"123", green:"155", blue:"244|155"}

How should I proceed?

like image 538
David Avatar asked Feb 16 '16 09:02

David


3 Answers

No need for regexes:

parse = function(s) {
    return {
        red:   parseInt('+' + s, 10) || 0,
        green: parseInt(s.split('|')[1], 10) || 0,
        blue:  parseInt(s.split('-')[1], 10) || 0,
    };
};

//

test = [
    '123',
    '222|333-444',
    '55-66|77',
    '123|456',
    '123-456',
    '|123-456',
    '-123|456',
    '010|020-030',
  
];
  
test.map(parse).forEach(r => 
   document.write('<pre>' + JSON.stringify(r) + '</pre>'));

This uses the fact that parseInt stops at the first non-parseable character and returns a falsy value when given garbage. The '+' + s hack is to invalidate the leading dash (which otherwise would be mistaken for the minus sign).

like image 52
georg Avatar answered Oct 09 '22 11:10

georg


You are probably best using a Regexp to match this - one for each section of the string.

exec() each Regex and the match will be stored in index 1 of the resulting array. If there is no match, then null is returned from exec(), so use a dummy array of [null, 0] simplify things.

Although not a requirement, this also works if there is no red value.

function getRGB() {
  var reRed = /^([0-9]+)/; // start of string (^) then match 1+ numbers
  var reGreen = /\|([0-9]+)/; // a "|" then match 1+ numbers
  var reBlue = /-([0-9]+)/;  // a "-" then match 1+ numbers

  return {
    red: (reRed.exec(input) || [null, 0])[1],
    green: (reGreen.exec(input) || [null, 0])[1],
    blue: (reBlue.exec(input) || [null, 0])[1]
  };
}

// RGB
var input = '123|155-244';
console.log(input, getRGB(input));

// RBG
var input = '123-244|155';
console.log(input, getRGB(input));

// RB
input = '123-244';
console.log(input, getRGB(input));

// BG
var input = '-244|155';
console.log(input, getRGB(input));
like image 45
Rhumborl Avatar answered Oct 09 '22 11:10

Rhumborl


You can use String#match with RegEx.

var str = '123|155-244';

var result = {
    red: (str.match(/^\d+/) || [0])[0], // Get first digits or zero
    green: (str.match(/\|(\d+)/) || [0, 0])[1], // Get digits after `|` or zero
    blue: (str.match(/-(\d+)/) || [0, 0])[1] // Get digits after `-` or zero
};

console.log(result);
document.getElementById('pre').innerHTML = JSON.stringify(result, 0, 4);
<pre id="pre"></pre>

Original answer

Misunderstood that - and | are interchangeable, but the sequence of colors will be fixed as Red, Green and then Blue.

You can use String#split with regex.

var str = '123|155-244';
var colors = ['red', 'green', 'blue'];
var result = {};

var arr = str.split(/\||-/g);
arr.forEach((e, i) => result[colors[i]] = arr[i]);

console.log(result);
document.getElementById('result').innerHTML = JSON.stringify(result, 0, 4);
<pre id="result"></pre>

Regex Explanation:

The simple regex \||- will split the string by pipe | or -.

Another live demo:

var colors = ['red', 'green', 'blue'];

document.getElementById('input').addEventListener('keyup', function() {
  var str = this.value;
  var result = {};

  var arr = str.split(/\||-/g);
  arr.forEach((e, i) => result[colors[i]] = arr[i]);
  console.log(result);
  document.getElementById('result').innerHTML = JSON.stringify(result, 0, 4);
}, false);
<input id="input" />

<pre id="result"></pre>
like image 43
Tushar Avatar answered Oct 09 '22 12:10

Tushar