Very new to node.js, I have string returning from RPGLE (as400) program, I would like to return as JSON example below.
String
{orderid:996553,workorder:996553.010,shipped:000000001,received:000000001,status:GOOD},
{orderid:996554,workorder:996554.010,shipped:000000001,received:000000001,status:GOOD},
{orderid:999290,workorder:999290.010,shipped:000000001,received:000000001,status:GOOD},
{orderid:999290,workorder:999290.020,shipped:000000001,received:000000001,status:GOOD},
{orderid:999290,workorder:999290.030,shipped:000000001,received:000000001,status:GOOD},
{orderid:999290,workorder:999290.040,shipped:000000001,received:000000001,status:GOOD},
{orderid:999290,workorder:999290.050,shipped:000000001,received:000000001,status:GOOD},
Would like to convert as below and send to application api
[{"orderid":144234,"workorder":"996553.010","shipped":1,"received":1,"status":"GOOD"},
{"orderid":999290,"workorder":"996553.010","shipped":1,"received":1,"status":"GOOD"},
{"orderid":999290,"workorder":"999290.010","shipped":1,"received":1,"status":"GOOD"},
{"orderid":999290,"workorder":"999290.020","shipped":1,"received":1,"status":"BAD"},
{"orderid":999290,"workorder":"999290.030","shipped":1,"received":1,"status":"GOOD"},
{"orderid":999290,"workorder":"999290.040","shipped":1,"received":1,"status":"GOOD"},
{"orderid":999290,"workorder":"999290.050","shipped":1,"received":1,"status":"GOOD"}]
What would be the best practice and how?
You can accomplish this string conversion through a series of regular expressions and a little decision logic to determine string and numeric values.
var meh = "{orderid:996553,workorder:996553.010,shipped:000000001,received:000000001,status:GOOD},\
{orderid:996554,workorder:996554.010,shipped:000000001,received:000000001,status:GOOD},\
{orderid:999290,workorder:999290.010,shipped:000000001,received:000000001,status:GOOD},\
{orderid:999290,workorder:999290.020,shipped:000000001,received:000000001,status:GOOD},\
{orderid:999290,workorder:999290.030,shipped:000000001,received:000000001,status:GOOD},\
{orderid:999290,workorder:999290.040,shipped:000000001,received:000000001,status:GOOD},\
{orderid:999290,workorder:999290.050,shipped:000000001,received:000000001,status:GOOD},";
meh = "[" + // enclose with []
meh.replace(/(\w+)(?=:)/g, '"$1"') // search for words followed by a colon
.replace(/,$/, '') // trim the ending comma
.replace(/:([\w.]+)/g, function(match, value){ // grab the values
return ':' + ( // ensure preceding colon is in place
isNaN(value) || value % 1 !== 0 ? // is it a non-float number?
'"' + value + '"' : // enclose with "" if not a non-float number
parseFloat(value) // parse if is number
);
})
+ "]"; // enclose with []
console.log(JSON.parse(meh));
You could parse the lines into valid javascript objects and then stringify them into JSON like this:
const s = `
{orderid:996553,workorder:996553.010,shipped:000000001,received:000000001,status:GOOD},
{orderid:996554,workorder:996554.010,shipped:000000001,received:000000001,status:GOOD},
{orderid:999290,workorder:999290.010,shipped:000000001,received:000000001,status:GOOD},
{orderid:999290,workorder:999290.020,shipped:000000001,received:000000001,status:GOOD},
{orderid:999290,workorder:999290.030,shipped:000000001,received:000000001,status:GOOD},
{orderid:999290,workorder:999290.040,shipped:000000001,received:000000001,status:GOOD},
{orderid:999290,workorder:999290.050,shipped:000000001,received:000000001,status:GOOD},
`;
const array = s.trim().split("\n").map((line) =>
line
.slice(1, -2) // remove brackets and comma
.split(",") // break into individual key/value pairs
.map((pair) => pair.split(":")) // split key/value pairs
.reduce((result, [key, value]) => { // reduce pairs into an object
result[key] = value;
return result;
},{})
);
const json = JSON.stringify(array, null, 2);
console.log(json);
How is the RPGLE program creating the string? If it is doing it piece by piece, then the RPGLE program could probably add the quotes and format the numbers correctly.
Related
I am having a string like "['a','b','c']"
How can I convert it to array?
I have tried JSON.parse but it is giving error at position 1.
Whilst it is unsafe (and you should think about the full consequences first), a very obvious solution could be using eval(). I am aware that you can mitigate it using sandboxing, but you should avoid it at all costs.
console.log(eval("['a','b','c']"));
So, what can we do?
Here's a simple hack:
console.log(
"['a','b', 'c']".split(`',`).map(a => a.replace(/\s*[\[\]"']\s*/g, ''))
);
But maybe you want to preserve those characters using backslashes.
console.log(
"['a', 'b','c' ]"
.split(/(?<!\\),/g)
.map((a, i, arr) => {
if (i === 0) return a.slice(1);
if (i === arr.length - 1) return a.slice(0, -1);
return a;
})
.map(a => a.trim().replace(/(?<!\\)'/g, ''))
);
But using negative look behinds aren't widely supported.
console.log(
"[ 'a','b' ,'c', '\\'d']" // Still a valid array
.slice(1, -1) // Remove [ and ] by slicing first and last characters
.split(`\\'`) // Split by \\'
.map(a => // Iterate through and return array with result
a.replace(/'/g, '') // Replace ' with nothing
.trim() // Trim trailing spaces
)
.join(`\\'`) // Join using \\'
.split(',') // Split up into array by ,
);
Use this:
function toArray(input) {
input = input.replace(/\"/g, "").replace(/\'/g, "\"")
return JSON.parse(input)
}
It converts the string "['a', 'b', 'c']" into the array ["a", "b", "c"].
I have a string that I need to split by a certain delimiter and convert into an array, but without removing the delimiter itself.
For example, consider the following code:
var str = "#mavic#phantom#spark";
str.split("#") //["", "mavic", "phantom", "spark"]
I need the output to be as follows:
["#mavic", "#phantom", "#spark"]
I read here but that does not answer my question.
You could split by positive lookahead of #.
var string = "#mavic#phantom#spark",
splitted = string.split(/(?=#)/);
console.log(splitted);
Split the string by # and use the reduce to return the modified string
var str = "#mavic#phantom#spark";
let x = str.split("#").reduce((acc, curr) => {
if (curr !== '') {
acc.push('#' + curr);
}
return acc;
}, [])
console.log(x)
Here is also some non-regexp methods of solving your task:
Solution 1 classical approach - iterate over the string and each time when we find indexOf our delimiter, we push to the result array the substring between current position and the next position. In the else block we have a case for the last substring - we simply add it to the result array and break the loop.
const delimiter = '#';
const result1 = [];
let i = 0;
while (i < str.length) {
const nextPosition = str.indexOf(delimiter, i+1);
if (nextPosition > 0) {
result1.push(str.substring(i, nextPosition));
i = nextPosition;
} else {
result1.push(str.substring(i));
break;
}
}
Solution 2 - split the initial string starting at index 1 (in order to not include empty string in the result array) and then just map the result array by concatenating the delimiter and current array item.
const result2 = str.substr(1).split(delimiter).map(s => delimiter + s);
another way:
filter empty elements after splitting, and map these elements to start with the character you splitted with.
string.split("#").filter((elem) => elem).map((elem) => "#" + elem);
var string;
var splitstring = string.split("????");
my string is 12BLG123
i need the array splitstring to have elements 12,BLG,123
(The alphabets and numbers randomly vary)
const string = `12BLG123`
const splitString = string.split(/(\d+)/).filter(i => i)
console.log(splitString)
The regex splits the string by numeric strings. Since split doesn't include the value that it is being split by, we use the capturing syntax to include the numeric strings. Empty strings are introduced if the string starts or ends with numeric strings so we use filter(i => i) to remove the empty strings (it works because empty strings are falsey values in javascript).
Though not regex or split, but you can do something like this,
var str = "12BLG123";
var result = [].reduce.call(str, (acc, a) => {
if (!acc.length) return [a]; // initial case
let last = acc[acc.length - 1];
// same type (digit or char)
if (isNaN(parseInt(a, 10)) == isNaN(parseInt(last.charAt(0), 10)))
acc[acc.length - 1] = last + a;
// different type
else acc.push(a);
// return the accumulative
return acc;
}, [] /* the seed */);
console.log(result);
This regex will probably work.
var splitString = string.split("[^A-Z0-9]+|(?<=[A-Z])(?=[0-9])|(?<=[0-9])(?=[A-Z])");
How can I convert this string: "{one=1,two=2}" into an object with JavaScript? So I can access the values.
I tried replacing the "=" for ":", but then while accessing the object I receive an "undefined". Here is my code:
var numbers = "{one=1,two=2}"; //This is how I receive the string
numbers = numbers.replace(/=/g, ':'); //I use the '/g' to replace all the ocurrencies
document.write(numbers.one); //prints undefined
So this is the string
var str = '{one=1,two=2}';
replace = character to : and also make this as a valid JSON object (needs keys with double-quotes around)
var str_for_json = str.replace(/(\w+)=/g, '"$1"=').replace(/=/g, ':');
In regex, \w means [a-zA-Z0-9_] and the ( ) capture what's inside, usable later like here with $1
Now parse your string to JSON in order to use like that
var str_json = JSON.parse(str_for_json);
Now enjoy. Cheers!!
document.write(str_json.one);
FINALLY :
var str = '{one=1,two=2}';
var str_for_json = str.replace(/(\w+)=/g, '"$1"=').replace(/=/g, ':');
try {
var str_json = JSON.parse(str_for_json);
document.write(str_json.one);
} catch(e) {
console.log("Not valid JSON:" + e);
};
Instead of trying to use regexp to create JSON, I would simply parse the string directly, as in
const result = {};
numbers.match(/{(.*?)}/)[1] // get what's between curlies
.split(',') // split apart key/value pairs
.map(pair => pair.split('=')) // split pairs into key and value
.forEach(([key, value]) => // for each key and value
result[key] = value); // set it in the object
1 - a valide JSON is :var numbers = "{\"one\"=1,\"two\"=2}"; (you need the \")
2- you need to JSON.parse the strign
So this works:
var numbers = "{\"one\"=1,\"two\"=2}"; //This is how I receive the string
numbers = numbers.replace(/=/g, ':'); //I use the '/g' to replace all the ocurrencies
numbers=JSON.parse(numbers);
document.write(numbers.one); //prints undefined
But, it's bad practice !
So I have a textarea with content, only numbers and | (separators). Example :
<textarea>32|11|5|54|</textarea>
What I'd like is to append the textarea content, delete only the separators (the |) and keep the numbers, in their order. Get that kind of array :
var myArray = [22,9,54,37];
Note that I'm only allowed to basic JS
I know how to get the textarea content in a string, but I don't see how can I push() all the elements in an array, without breaking the numbers (ie having 2,2,9,5,4,3,7 instead of 22,9,54,37) AND deleting the separators. If needed I can change the separator, that's not a problem.
Pre-thanks.
Use split to split the string based on the separator.
Use .filter to remove empty values
Use .map to cast string to Number
Try this:
var val = document.getElementById('ta').value;
var arr = val.split('|').filter(function(item) {
return item; //empty string is falsey value
}).map(Number); // cast string to Number
console.log(arr);
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<textarea id='ta'>32|11|5|54|</textarea>
You could use the split() function in javascript, and pass it the | as a parameter. This will create an array that contains all the numbers in order, without the | symbol.
If you need the numbers in order, then you can use the .join() with , passed in to create a string for output.
Javascript:
var textarea = document.getElementById( "textarea" ).value;
var values = textarea.split('|');
var valuesAsString = values.join(', ');
HTML:
<textarea id="textarea">32|11|5|14</textarea>
use trim in filter condition to check empty values.
try this
var res = '32|11|5|54|'.split('|').filter(function(v) {
return v.trim() != ''
})
document.write('<pre>' + JSON.stringify(res, 0, 4) + '</pre>')
res = '32|11||5|54|'.split('|').filter(function(v) {
return v.trim() != ''
})
document.write('<pre>' + JSON.stringify(res, 0, 4) + '</pre>')
res = '32|11| |5|54|'.split('|').filter(function(v) {
return v.trim() != ''
})
document.write('<pre>' + JSON.stringify(res, 0, 4) + '</pre>')
You're looking for the String.prototype.split method which accepts separator as an argument. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split
So in your case it will be '22|33|44'.split('|')
If you want add these values to an existing array, you should use Array.prototype.conat method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat