Avoid escape sequence and split the string in Javascript - javascript

I have a requirement to split the below string and get the values. Have tried with the JS string split method but it is not working for backslash split(). Please help me. Thanks in advance.
Input string = "11,22;0:0/0\0}0#0&"
Output:
, => 11,
; => 22
: => 0
/ => 0
\ => 0
} => 0
# => 0
& => 0

I made a modification with reference to a lot of reading. Hope you find this useful. The '0' with an escape character is also printed in this solution. Please check it.
let string = "26,67;4:79/9\0}0&";
string = encodeURI(string);
string = string.replace("%0", "&");
string = decodeURI(string);
numbers = string.split(/,|;|:|\/|\\|}|&/);
finalList = [];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] != "")
finalList.push(parseInt(numbers[i]));
}
console.log(finalList);

It is working fine for me. Please try the below code.
let string = "26,67;4:79/9\0}0&";
let arr = string.split(/,|;|:|\/|\\|}|&/); // ["26", "67", "4", "79", "9 ", "0", ""]
Thank you...

Related

How To Get An Array From Splitted String That Has Negative Value

I don't know what is the right question for this.
I want to make this number -800 become [-8,0,0] is anyone can build it
The first thing that I do, is to make the number become a string and using the map function I iterate it becomes an array like this
const number = -800;
const numberString = number.toString();
const arrayString = numberString.split``.map((x) => +x);
console.log(arrayString)
But the result is [ NaN, 8, 0, 0 ]
How to change the NaN and first index 8 become -8 without disturbing the other index. So it becomes [-8, 0, 0]
Is anybody can help me?
Thanks.
Try numberString.match(/-?\d/g) instead of split
const number = -800;
const numberString = number.toString();
const arrayString = numberString.match(/-?\d/g).map(x => +x);
console.log(arrayString)
One possible solution is to just do this operation on the absolute value and, during the map, check if the number was negative (only for the first index).
const number = -800;
const numberString = Math.abs(number).toString();
const arrayString = numberString.split``.map((x, i) => i == 0 && number < 0 ? -x : +x);
console.log(arrayString)
If you're not clear about Regex, you can use Array.from to convert a string to an array number. Then handle the first number based on the sign of original number.
console.log(convertNumberToArray(800));
console.log(convertNumberToArray(-800));
function convertNumberToArray(number){
var result = Array.from(Math.abs(number).toString(), Number);
result[0] *= number <= 0 ? -1 : 1;
return result;
}
Use String#match with regex which matches optional - with the dig it.
var number = -800;
var numberString = number.toString().match(/-?\d/g);
var numberInt = [];
for (var i = 0; i < numberString.length; i++) {
numberInt.push(parseInt(numberString[i]));
}
console.log(numberInt);

string compression counting the repeated character in javascript

If I have a string a12c56a1b5 then out put should be a13b5c56 as character a is repeated twice so a12 becomes a13
I have tried this:
function stringCompression (str) {
var output = '';
var count = 0;
for (var i = 0; i < str.length; i++) {
count++;
if (str[i] != str[i+1]) {
output += str[i] + count;
count = 0;
}
}
console.log(output); // but it returns `a11121c15161a111b151` instead of `a13b5c56`
}
It is happening because the code is counting the occurrence of each element and appending it, even the numbers in the string.
In this code,
for (var i = 0; i < str.length; i++) {
count++;
if (str[i] != str[i+1]) {
output += str[i] + count;
count = 0;
}
}
in first iteration i = 0, str[i] = 'a' and str[i + 1] = '1' for the given string a12c56a1b5 which are not equal hence, it will generate the output as a1 for first iteration, then a111 for second iteration since str[i] = '1' and str[i + 1] = '2' now, and so on.
We can achieve this by first separating the characters from the count. Assuming, that there would be characters from a-z and A-Z only followed by the count. We can do something like this, str.match(/[a-zA-Z]+/g) to get the characters: ["a", "c", "a", "b"] and str.match(/[0-9]+/g) to get their counts: ["12", "56", "1", "5"], put them in an object one by one and add if it already exists.
Something like this:
function stringCompression(str) {
var characters = str.match(/[a-zA-Z]+/g);
var counts = str.match(/[0-9]+/g);
var countMap = {};
for (var i = 0; i < characters.length; i++) {
if (countMap[characters[i]]) {
countMap[characters[i]] += parseInt(counts[i]);
} else {
countMap[characters[i]] = parseInt(counts[i]);
}
}
var output = Object.keys(countMap)
.map(key => key + countMap[key])
.reduce((a, b) => a + b);
console.log(output);
}
stringCompression('a12c56a1b5')
Using regex to extract word characters and numbers. Keeps an object map res to track and sum up following numbers. sorts and converts back to a string.
As an example, the for-of loop iteration flow with str=a12c56a1b5:
c='a', n='12'
res['a'] = (+n = 12) + ( (res['a'] = undefined)||0 = 0)
or ie: res['a'] = 12 + 0
c='c', n='56'
res['c'] = 56 + 0
c='a', n='1'
res['a'] = 1 + (res['a'] = 12 from iteration 1.) = 13
c='b', n='5'
res['b'] = 5 + 0
thus res = { 'a': 13, 'c': 56, 'b': 5 } after the for-of loop finishes
function stringCompression (str) {
// build object map with sums of following numbers
const res = {}
for(const [,c,n] of str.matchAll(/(\w+)(\d+)/g))
res[c] = +n + (res[c]||0)
// convert object map back to string
output = Object.entries(res)
output.sort(([a],[b])=>a<b ? -1 : a>b ? 1 : 0)
output = output.map(([a,b])=>`${a}${b}`).join('')
console.log(output); // but it returns `a11121c15161a111b151` instead of `a13b5c56`
}
stringCompression('a12c56a1b5')
[,c,n] = [1,2,3] is equivalent to c=2, n=3. It is called destructuring.
matchAll matches on a regex. It's a relatively new shorthand for calling .exec repeatedly to execute a regular expression that collects all the results that the regular expression matches on.
(\w+)(\d+) is a regex for two capture groups,
\w+ is for one or more alpha characters, \d+ is for one or more digits.
for(const [,c,n] of str.matchAll...) is equivalent to:
for each M of str.matchAll...
const c = M[1], n = M[2]`
res[c]||0 is shorthand for:
"give me res[c] if it is truthy (not undefined, null or 0), otherwise give me 0"
+n uses the unary operator + to force an implicit conversion to a number. JavaScript specs for + unary makes it convert to number, since + unary only makes sense with numbers.
It is basically the same as using Number(n) to convert a string to an number.
Conversion back to a string:
Object.entries converts an object {"key":value} to an array in the form of [ [key1, value1], [key2, value2] ]. This allows manipulating the elements of an object like an array.
.sort sorts the array. I destructured the keys to sort on the keys, so "a" "b" "c" are kept in order.
.map takes an array, and "maps" it to another array. In this case I've mapped each [key,value] to a string key+value, and then taking the final mapped array of key+value strings and joined them together to get the final output.
In case it asks you to sort it alphabetically, I added #user120242's sorting code snippet to #saheb's entire answer (in between Object.keys(countMap) and .map(...). That worked for me. I tried using #user120242's whole answer, but it did not pass all the tests since it did not add the repeated letters for longer strings. But #user120242's answer did work. It just need to be sorted alphabetically and it passed all the test cases in HackerRank. I had this question for a coding assessment (called "Better Coding Compression").
P.S. I also removed checking the capital letters from #saheb's code since that wasn't required for my coding challenge.
Here's how mine looked like:
function stringCompression(str) {
var characters = str.match(/[a-zA-Z]+/g);
var counts = str.match(/[0-9]+/g);
var countMap = {};
for (var i = 0; i < characters.length; i++) {
if (countMap[characters[i]]) {
countMap[characters[i]] += parseInt(counts[i]);
} else {
countMap[characters[i]] = parseInt(counts[i]);
}
}
var output = Object.keys(countMap)
.sort(([a],[b])=>a<b ? -1 : a>b ? 1 : 0)
.map(key => key + countMap[key])
.reduce((a, b) => a + b);
console.log(output);
}
stringCompression('a12c56a1b5')

How can i print only letters?

I'm trying to do a caesar cipher in javascript, I'm very new at this. I know i have to limit the ascii so that it's only letters. Because like this if we insert the letter "z" and the key "3" it won't give us "c", but something else. I've tried to search but i can't seem to understand how to do that. Thanks in advance for any help.
var letter=readLine("letter?");
var key=parseInt(readLine("key?"));
var result= letter.charCodeAt(0)+key;
print(String.fromCharCode(result));
If I understand correctly, it should work:
for(var i =0; i<letter.length;i++){
print(String.fromCharCode(letter.charCodeAt(i) + key))
}
I know this is an outdated question but since no one has posted the answer:
To shift only letters you can use this:
caesarCipher = (s, k) => {
let string = s;
string = string.replace(/[a-z]/g, str => String.fromCharCode((str.charCodeAt(0) - 97 + k) % 26 + 97));
string = string.replace(/[A-Z]/g, str => String.fromCharCode((str.charCodeAt(0) - 65 + k) % 26 + 65));
return string;
}

Javascript replace every 6th colon in array

I have some problems with replacing every 6th colon in my array. Have tried something with Regex, but that doesn't seem to work. I have red other questions were people are using nth and then set this variabele to the index you want to replace, but can't figure out why that isn't working. I used the join function to replace the ',' in my array with ':'.
arrayProducts[i] = arrayProducts[i].join(':');
When i use console.log(arrayProducts); this is my result:
F200:0:0.0000:1:100:0:1:KPO2:0:0.0000:1:200:0:2:HGB1:0:0.0000:1:300:0:3
This is what I want:
F200:0:0.0000:1:100:0:1,KPO2:0:0.0000:1:200:0:2,HGB1:0:0.0000:1:300:0:3
Thanks for reading!
Edit: F200, KP02 and HGB1, could also be numbers / digits like: 210, 89, 102 so the :[A-Z] method from regex doesn't work.
You can just count the number of colon occurences and replace every nth of them.
var str = 'F200:0:0.0000:1:100:0:1:KPO2:0:0.0000:1:200:0:2:HGB1:0:0.0000:1:300:0:3', counter = 0;
res = str.replace(/:/g, function(v) {
counter++;
return !(counter % 7) ? ',' : v;
});
console.log(res);
A regex solution is viable. You can use a function as the second parameter of the .replace method to make full use of backreferences.
var str = 'F200:0:0.0000:1:100:0:1:KPO2:0:0.0000:1:200:0:2:HGB1:0:0.0000:1:300:0:3';
str = str.replace(/((?:[^:]*:){6}(?:[^:]*)):/g, function() {
var matches = arguments;
return matches[1] + ',';
});
console.log(str);
What you are looking for is to split over the following expression :[A-Z]
(assuming that your rows always start with this range)
a simple solution could be:
mystring.split(/:[A-Z]/).join(',')
/:[A-Z]/ matches any : followed by a uppercase letter
You could use replace with a look for six parts with colon and replace the seventh.
var string = 'F200:0:0.0000:1:100:0:1:KPO2:0:0.0000:1:200:0:2:HGB1:0:0.0000:1:300:0:3',
result = string.replace(/(([^:]*:){6}[^:]*):/g, '$1,');
console.log(result);
Another solution (based on the number of iteration)
using map method:
str.split(':').map((v, i) => (i % 7 === 0 ? ',' : ':') + v ).join('').slice(1)
using reduce method:
str.split(':').reduce((acc,v, i) => {
return acc + (i % 7 === 0 ? ',' : ':' ) + v ;
}, '').slice(1)
Note: arrow expression does not work on old browsers
maybe you can try this approach,
loop your array and join it manually, something like :
var strarr = "F200:0:00000:1:100:0:1:KPO2:0:00000:1:200:0:2:HGB1:0:00000:1:300:0:3";
var arr = strarr.split(":")
var resStr = "";
for(var i = 0; i < arr.length; i++)
{
if(i > 0 && i%7 == 0)
resStr = resStr + "," + arr[i]
else
resStr = resStr + ( resStr == "" ? "" : ":") + arr[i];
}
console.log(resStr);

data encoding for JSON.parse( ) unexpected token

I am pulling down some data from my server and manipulating it and then trying to load the string into an object using JSON.parse(). However whenever I try to do it I get an Unexpected Token error. The weird thing is that usually chrome tells me what the unexpected token is (usually 'o' or something). This time it is just a space. Which makes me think that there is some type of ascii encoding error or something going on. If I print the json string to the console doing console.log() and then paste it directly into the code then it has no problem parsing the string.
var testString = '[ { "pk": 1663, "state": "IO", "group": "ALO", "species": "", "application_link": "" } ]';
var testObject = JSON.parse(testString);
alert(testObject);
Works exactly how I expect it to. But this doesn't:
function hex2ascii(hexx) { //stolen off stackoverflow
var hex = hexx.toString();//force conversion
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
function decodeData(encoded){
var original_string = '';
for (var i = 0; i < encoded.length; i+=2) {
var index = i/2;
var hex_value = encoded[i]+encoded[i+1];
var ochar = hex2ascii(hex_value);
original_string += ochar;
}
return original_string;
}
$.get(url, function(data) {
var testString = decodeData(data); //decodeData grabs a hex string and then decodes it into a json formatted string
var testObject = JSON.parse(testString); //Unexpected Token
alert(testObject);
});
Anybody have any ideas on how to go about troubleshooting this?
Edit:
I don't know why but I have a bunch of null's in my string. When I iterate through the json string and convert it back to hex I get:
hex_string = ''
for(var i = 0; i < decoded_data.length; i++){
if (i < 10){
alert(decoded_data[i]);
}
hex_string += ascii2hex(decoded_data[i])+' ';
}
console.log(hex_string);
>>>0 0 5b 0 0 7b 0 0 22 0 0 70 0 0 6b 0 0 22 0 0 3a 0 0 20 0 0 31 0 0 36 0 0 36 0 0
Edit again:
Ok so I have pinned it down to my concatenation method. For some reason in the decodeData function when I concatenate it together doing
original_string += ochar;
It's throwing in a bunch of null characters. Is there another way to concatenate the string together?
Edit answer:
Ok, so the problem lied within the hex2ascii function. It was adding in a bunch of null characters. It was code I stole off of stack overflow and wasn't what I expected. I ended up changing it to this and now it's golden.
function hex2ascii(hexx) {
var hex = hexx.toString();//force conversion
return String.fromCharCode(parseInt(hex, 16));
}
you could not juz input break line in javascript string, it will make it invalid.
Invalid
var testString = '[ {
"pk": 1663,
"state": "IO",
"group": "ALO",
"species": ""
]}';
Valid
var testString = '[ {"pk": 1663,"state": "IO","group": "ALO","species": ""]}';
I think that the reason you are getting an Unexpected Token error is because you have that extra close parenthesis on the line that says
$.get(url, function(data)) {
and you are missing a parenthesis at the end.
Ok, so the problem lied within the hex2ascii function. It was adding in a bunch of null characters. It was code I stole off of stack overflow and wasn't what I expected. I ended up changing it to this and now it's golden.
function hex2ascii(hexx) {
var hex = hexx.toString();//force conversion
return String.fromCharCode(parseInt(hex, 16));
}

Categories