Say I have two string variables:
a = 'LOVE';
b = '....';
How do I use regex (or whatever else is fastest) to combine a + b to make:
c = 'L.O.V.E.';
In my case, both strings are 4 characters long, always, and the second string is not a fixed character, I just made it a dot to make it look clearer on screen.
You can simply loop through the longer string and in each iteration append one character from both strings to your resulting string. I don't think you need any regular expression there:
a = 'LOVE';
b = '....';
var combinedString = '';
var largerLength = Math.max( a.length, b.length );
for( var i = 0; i < largerLength; i++ )
{
combinedString += a.charAt(i) + b.charAt(i);
}//for()
console.log( combinedString );
The above code will work for strings of any length. In case, you know beforehand that both strings are exactly 4 characters long, I think the fastest and most efficient way would be:
a = 'LOVE';
b = '....';
var combinedString = a.charAt[0] + b.charAt[0] + a.charAt[1] + b.charAt[1] + a.charAt[2] + b.charAt[2] + a.charAt[3] + b.charAt[3];
console.log( combinedString );
You could use Array#reduce for it
var a = 'LOVE',
b = '....';
c = a.split('').reduce(function (r, v, i) {
return r + v + b[i];
}, '');
console.log(c);
How to combine a + b via regex:
var a = "LOVE", b = "....";
var result = a.replace(/./g, (match, i) => match + b[i]);
console.log(result);
There is no need of regex for your problem. You can simply do it with the help of for loop
a = 'LOVE';
b = '....';
var result = '';
var length = Math.max( a.length, b.length );
for( var i = 0; i <+ length-1; i++ )
{
result = result + a.charAt(i);
result = result + b.charAt(i);
}
alert("Result of combined string is :"+ result);
You can use array functions on array likes (in this example strings) to iterate over it's items.
var a = 'LOVE',
b = '....',
c = Array.prototype.map
.call(a, (v, i) => v + b[i]).join('');
console.log(c);
If your second string is always composed of dots, instead of repeating same characters in string, try something like this:
Using Delimiter
var a = "LOVE";
var delimeter = ".";
var result = a.split("").join(delimeter) + delimeter;
console.log(result)
Array convert + manual concatenation
As an alternate to string.charAt, you can try something like this:
Note: you should do a1[i] || "" for cases where value can be undefined. Also you should use .toString() to avoid cases where both values are numeric and result will be addition instead of concatenation.
var a = 'LOVE';
var b = '....';
var c = ",,,,,,,,,,,";
function mergeStr(a, b) {
var a1 = a.split("");
var b1 = b.split("");
var len = Math.max(a.length, b.length)
var r = "";
for (var i = 0; i < len; i++) {
r += (a1[i] || "").toString() + (b1[i] || "").toString();
}
return r;
}
console.log(mergeStr(a,b))
console.log(mergeStr(a,c))
Related
Let's say I have this string: "a_b_c_d_restofthestring" and I only want to keep (e.g.) 2 underscores. So,
"a_b_cdrestofthestring"
"abc_d_restofthestring"
Are both valid outputs.
My current implementation is:
let str = "___sdaj___osad$%^&*";
document.getElementById('input').innerText = str;
let u = 0;
str = str.split("").reduce((output, c) => {
if (c == "_") u++;
return u < 2 || c != "_" ? output + c : output;
});
document.getElementById('output').innerText = str;
<div id="input"></div>
<div id="output"></div>
But I'd like to know if there's a better way...
Your code seems to work fine, but here's a one-liner regular expression that replaces all but the last two underscores from the input string.
let input = "___sdaj___osad$%^&*";
let output = input.replace(/_(?=(.*_){2})/g, '');
console.log("input: " + input);
console.log("output: " + output);
This of course is not very generalized, and you'd have to modify the regular expression every time you wanted to say, replace a character other than underscore, or allow 3 occurrences. But if you're okay with that, then this solution has a bit less code to maintain.
Update: Here's an alternate version, that's fully generic and should perform a bit better:
let input = "___sdaj___osad$%^&*";
function replace(input, char = '_', max = 2, replaceWith = '') {
let result = "";
const len = input.length;
for (let i = 0, u = 0; i < len; i++) {
let c = input[i];
result += (c === char && ++u > max) ? replaceWith : c;
}
return result;
}
console.log("input: ", input);
console.log("output: ", replace(input));
See this jsPerf analysis.
You could take a regular expression which looks for an underscore and a counter of the keeping underscores and replace all others.
var string = "a_b_c_d_restofthestring",
result = string.replace(/_/g, (c => _ => c && c-- ? _ : '')(2));
console.log(result);
I have string like:
MPG_0023
I want to find something like
MPG_0023 + 1
and I should get
MPG_0024
How to do that in JavaScript? It should take care that if there are no leading zeros, or one leading zero should still work like MPG23 should give MPG24 or MPG023 should give MPG024.
There should be no assumption that there is underscore or leading zeros, the only thing is that first part be any string or even no string and the number part may or may not have leading zeros and it is any kind of number so it should work for 0023 ( return 0024) or for gp031 ( return gp032) etc.
Here's a quick way without using regex.. as long as there's always a single underscore preceding the number and as long as the number is 4 digits, this will work.
var n = 'MPG_0023';
var a = n.split('_');
var r = a[0]+'_'+(("0000"+(++a[1])).substr(-4));
console.log(r);
Or if you do wanna do regex, the underscore won't matter.
var n = "MPG_0099";
var r = n.replace(/(\d+)/, (match)=>("0".repeat(4)+(++match)).substr(-4));
console.log(r);
You can use the regular expressions to make the changes as shown in the following code
var text = "MPG_0023";
var getPart = text.replace ( /[^\d.]/g, '' ); // returns 0023
var num = parseInt(getPart); // returns 23
var newVal = num+1; // returns 24
var reg = new RegExp(num); // create dynamic regexp
var newstring = text.replace ( reg, newVal ); // returns MPG_0024
console.log(num);
console.log(newVal);
console.log(reg);
console.log(newstring);
Using regex along with the function padStart
function add(str, n) {
return str.replace(/(\d+)/, function(match) {
var length = match.length;
var newValue = Number(match) + n;
return newValue.toString(10).padStart(length, "0");
});
}
console.log(add("MPG_023", 101));
console.log(add("MPG_0023", 101));
console.log(add("MPG_0000023", 10001));
console.log(add("MPG_0100023", 10001));
Using regular expression you can do it like this.
var text1 = 'MPG_0023';
var text2 = 'MPG_23';
var regex = /(.*_[0]*)(\d*)/;
var match1 = regex.exec(text1);
var match2 = regex.exec(text2);
var newText1 = match1[1] + (Number(match1[2]) + 1);
var newText2 = match2[1] + (Number(match2[2]) + 1);
console.log(newText1);
console.log(newText2);
Increment and pad the same value (comments inline)
var prefix = "MPG_"
var padDigit = 4; //number of total characters after prefix
var value = "MPG_0023";
console.log("currentValue ", value);
//method for padding
var fnPad = (str, padDigit) => (Array(padDigit + 1).join("0") + str).slice(-padDigit);
//method to get next value
var fnGetNextCounterValue = (value) => {
var num = value.substring(prefix.length); //extract num value
++num; //increment value
return prefix + fnPad(num, padDigit); //prepend prefix after padding
};
console.log( "Next", value = fnGetNextCounterValue(value) );
console.log( "Next", value = fnGetNextCounterValue(value) );
console.log( "Next", value = fnGetNextCounterValue(value) );
One way would e to split the string on the "_" character, increment the number and then add the zeros back to the number.
var testString = "MGP_0023";
var ary = testString.split("_");
var newNumber = Number(ary[1]) + 1;
var result = ary[0] + pad(newNumber);
// helper function to add zeros in front of the number
function pad(number) {
var str = number.toString();
while (str.length < 4) {
str = '0' + str;
}
return str;
}
You could cast to number, increment the value and cast back. Then check if you need leading zeros by looking at the length of the string.
Snippet below:
let str = "MPG_0023",
num = Number(str.substr(4)) + 1,
newStr = String(num);
function addLeading0(str) {
return str.length === 2 ? '00' + str : (str.length === 3 ? '0' + str : str);
}
console.log("MPG_" + addLeading0(newStr));
For example: m1 = m , m2 = mm, m3i2 = mmmii
I am trying to find a simple way to do this. Any useful methods?
This is not a homework problem. I am just practicing on my Javascript skills.
So easy with regex and repeat:
function f(str) {
return str.replace(/(.)(\d+)/g, (_, s, n) => s.repeat(n));
}
console.log(f('m1')); // 'm'
console.log(f('m2')); // 'mm'
console.log(f('m3i2')); // 'mmmii'
It can behave a bit inconsistent if the string starts with a digit. You may prefer /(\D?)(\d+)/g.
You could split the string and use the result for returning the string
var s = 'm3i2'.split(/(?=[a-z])/),
result = s.reduce(function (r, a) {
var i = +a.slice(1);
while (i--) {
r += a[0];
}
return r;
}, '');
console.log(result);
here in lambda style
"m2s3".split("").reduce((s,c) => isNaN(c) ? s + c : s + s[s.length-1].repeat(c-1));
mmsss
ES5 Example:
var s = 'm3i2j1';
var re = /([a-z])(\d+)/g;
var matches;
var buffer = [];
while (matches = re.exec(s)) {
buffer.push(Array(+matches[2] + 1).join(matches[1]));
}
var output = buffer.join('');
function replaceNumbers(text) {
var match = text.match(/\D\d*/g), ans = '', i, n;
for (i = 0; i < match.length; ++i) {
n = Number(match[i].substr(1));
ans += match[i].substr(0, 1).repeat(n > 0 ? n : 1);
}
return ans;
}
// Here is the solution I came up with.
function letTheNumberDoTheTalking(str) {
var word = '';
var start = 0;
for (var next = 1; next < str.length; next += 2) {
var letter = str[start];
var multipliedLetter = str[start].repeat(str[next]);
word += multipliedLetter;
start = next + 1;
}
return word;
}
letTheNumberDoTheTalking('m1i1s2i1s2i1p2i1')); //==> 'mississippi'
I want JavaScript to translate text in a textarea into binary code.
For example, if a user types in "TEST" into the textarea, the value "01010100 01000101 01010011 01010100" should be returned.
I would like to avoid using a switch statement to assign each character a binary code value (e.g. case "T": return "01010100) or any other similar technique.
Here's a JSFiddle to show what I mean. Is this possible in native JavaScript?
What you should do is convert every char using charCodeAt function to get the Ascii Code in decimal. Then you can convert it to Binary value using toString(2):
function convert() {
var output = document.getElementById("ti2");
var input = document.getElementById("ti1").value;
output.value = "";
for (var i = 0; i < input.length; i++) {
output.value += input[i].charCodeAt(0).toString(2) + " ";
}
}
<input id="ti1" value ="TEST"/>
<input id="ti2"/>
<button onClick="convert();">Convert!</button>
And here's a fiddle: http://jsfiddle.net/fA24Y/1/
This might be the simplest you can get:
function text2Binary(string) {
return string.split('').map(function (char) {
return char.charCodeAt(0).toString(2);
}).join(' ');
}
traverse the string
convert every character to their char code
convert the char code to binary
push it into an array and add the left 0s
return a string separated by space
Code:
function textToBin(text) {
var length = text.length,
output = [];
for (var i = 0;i < length; i++) {
var bin = text[i].charCodeAt().toString(2);
output.push(Array(8-bin.length+1).join("0") + bin);
}
return output.join(" ");
}
textToBin("!a") => "00100001 01100001"
Another way
function textToBin(text) {
return (
Array
.from(text)
.reduce((acc, char) => acc.concat(char.charCodeAt().toString(2)), [])
.map(bin => '0'.repeat(8 - bin.length) + bin )
.join(' ')
);
}
Here's a pretty generic, native implementation, that I wrote some time ago,
// ABC - a generic, native JS (A)scii(B)inary(C)onverter.
// (c) 2013 Stephan Schmitz <eyecatchup#gmail.com>
// License: MIT, http://eyecatchup.mit-license.org
// URL: https://gist.github.com/eyecatchup/6742657
var ABC = {
toAscii: function(bin) {
return bin.replace(/\s*[01]{8}\s*/g, function(bin) {
return String.fromCharCode(parseInt(bin, 2))
})
},
toBinary: function(str, spaceSeparatedOctets) {
return str.replace(/[\s\S]/g, function(str) {
str = ABC.zeroPad(str.charCodeAt().toString(2));
return !1 == spaceSeparatedOctets ? str : str + " "
})
},
zeroPad: function(num) {
return "00000000".slice(String(num).length) + num
}
};
and to be used as follows:
var binary1 = "01100110011001010110010101101100011010010110111001100111001000000110110001110101011000110110101101111001",
binary2 = "01100110 01100101 01100101 01101100 01101001 01101110 01100111 00100000 01101100 01110101 01100011 01101011 01111001",
binary1Ascii = ABC.toAscii(binary1),
binary2Ascii = ABC.toAscii(binary2);
console.log("Binary 1: " + binary1);
console.log("Binary 1 to ASCII: " + binary1Ascii);
console.log("Binary 2: " + binary2);
console.log("Binary 2 to ASCII: " + binary2Ascii);
console.log("Ascii to Binary: " + ABC.toBinary(binary1Ascii)); // default: space-separated octets
console.log("Ascii to Binary /wo spaces: " + ABC.toBinary(binary1Ascii, 0)); // 2nd parameter false to not space-separate octets
Source is on Github (gist): https://gist.github.com/eyecatchup/6742657
Hope it helps. Feel free to use for whatever you want (well, at least for whatever MIT permits).
var PADDING = "00000000"
var string = "TEST"
var resultArray = []
for (var i = 0; i < string.length; i++) {
var compact = string.charCodeAt(i).toString(2)
var padded = compact.substring(0, PADDING.length - compact.length) + compact
resultArray.push(padded)
}
console.log(resultArray.join(" "))
The other answers will work for most cases. But it's worth noting that charCodeAt() and related don't work with UTF-8 strings (that is, they throw errors if there are any characters outside the standard ASCII range). Here's a workaround.
// UTF-8 to binary
var utf8ToBin = function( s ){
s = unescape( encodeURIComponent( s ) );
var chr, i = 0, l = s.length, out = '';
for( ; i < l; i ++ ){
chr = s.charCodeAt( i ).toString( 2 );
while( chr.length % 8 != 0 ){ chr = '0' + chr; }
out += chr;
}
return out;
};
// Binary to UTF-8
var binToUtf8 = function( s ){
var i = 0, l = s.length, chr, out = '';
for( ; i < l; i += 8 ){
chr = parseInt( s.substr( i, 8 ), 2 ).toString( 16 );
out += '%' + ( ( chr.length % 2 == 0 ) ? chr : '0' + chr );
}
return decodeURIComponent( out );
};
The escape/unescape() functions are deprecated. If you need polyfills for them, you can check out the more comprehensive UTF-8 encoding example found here: http://jsfiddle.net/47zwb41o
Just a hint into the right direction
var foo = "TEST",
res = [ ];
foo.split('').forEach(function( letter ) {
var bin = letter.charCodeAt( 0 ).toString( 2 ),
padding = 8 - bin.length;
res.push( new Array( padding+1 ).join( '0' ) + bin );
});
console.log( res );
8-bit characters with leading 0
'sometext'
.split('')
.map((char) => '00'.concat(char.charCodeAt(0).toString(2)).slice(-8))
.join(' ');
If you need 6 or 7 bit, just change .slice(-8)
Thank you Majid Laissi for your answer
I made 2 functions out from your code:
the goal was to implement convertation of string to VARBINARY, BINARY and back
const stringToBinary = function(string, maxBytes) {
//for BINARY maxBytes = 255
//for VARBINARY maxBytes = 65535
let binaryOutput = '';
if (string.length > maxBytes) {
string = string.substring(0, maxBytes);
}
for (var i = 0; i < string.length; i++) {
binaryOutput += string[i].charCodeAt(0).toString(2) + ' ';
}
return binaryOutput;
};
and backward convertation:
const binaryToString = function(binary) {
const arrayOfBytes = binary.split(' ');
let stringOutput = '';
for (let i = 0; i < arrayOfBytes.length; i++) {
stringOutput += String.fromCharCode(parseInt(arrayOfBytes[i], 2));
}
return stringOutput;
};
and here is a working example: https://jsbin.com/futalidenu/edit?js,console
Provided you're working in node or a browser with BigInt support, this version cuts costs by saving the expensive string construction for the very end:
const zero = 0n
const shift = 8n
function asciiToBinary (str) {
const len = str.length
let n = zero
for (let i = 0; i < len; i++) {
n = (n << shift) + BigInt(str.charCodeAt(i))
}
return n.toString(2).padStart(len * 8, 0)
}
It's about twice as fast as the other solutions mentioned here including this simple es6+ implementation:
const toBinary = s => [...s]
.map(x => x
.codePointAt()
.toString(2)
.padStart(8,0)
)
.join('')
If you need to handle unicode characters, here's this guy:
const zero = 0n
const shift = 8n
const bigShift = 16n
const byte = 255n
function unicodeToBinary (str) {
const len = str.length
let n = zero
for (let i = 0; i < len; i++) {
const bits = BigInt(str.codePointAt(i))
n = (n << (bits > byte ? bigShift : shift)) + bits
}
const bin = n.toString(2)
return bin.padStart(8 * Math.ceil(bin.length / 8), 0)
}
this seems to be the simplified version
Array.from('abc').map((each)=>each.charCodeAt(0).toString(2)).join(" ")
This is as short as you can get. It's based on the top-rated answer but transformed to a reduce function.
"TEST".split("").reduce(function (a, b) { return a + b.charCodeAt(0).toString(2)}, "")
const textToBinary = (string) => {
return string.split('').map((char) =>
char.charCodeAt().toString(2)).join(' ');
}
console.log(textToBinary('hello world'))
var UTF8ToBin=function(f){for(var a,c=0,d=(f=unescape(encodeURIComponent(f))).length,b="";c<d;c++){for(a=f.charCodeAt(c).toString(2);a.length%8!=0;){a="0"+a}b+=a}return b},binToUTF8=function(f){for(var a,c=0,d=f.length,b="";c<d;c+=8){b+="%"+((a=parseInt(f.substr(c,8),2).toString(16)).length%2==0?a:"0"+a)}return decodeURIComponent(b)};
This is a small minified JavaScript Code to convert UTF8 to Binary and Vice versa.
This is a solution for UTF-8-based textual binary representation. It leverages TextEncoder, which encodes a string to its UTF-8 bytes.
This solution separates characters by spaces. The individual "byte-bits" of multi-byte characters are separated by a minus character (-).
// inspired by https://stackoverflow.com/a/40031979/923560
function stringToUtf8BinaryRepresentation(inputString) {
const result = Array.from(inputString).map(
char => [... new TextEncoder().encode(char)].map(
x => x.toString(2).padStart(8, '0')
).join('-')
).join(' ');
return result;
}
// ### example usage #########################
function print(inputString) {
console.log("--------------");
console.log(inputString);
console.log(stringToUtf8BinaryRepresentation(inputString));
}
// compare with https://en.wikipedia.org/wiki/UTF-8#Encoding
// compare with https://en.wikipedia.org/wiki/UTF-8#Codepage_layout
// compare with UTF-16, which JavaScript uses for strings: https://en.wikipedia.org/wiki/UTF-16#Examples
print("TEST");
print("hello world");
print("$");
print("Β£");
print("β¬");
print("ν");
print("π");
print("ΟΞ±ΟάδΡιγμα");
print("π€‘");
print("π¨βπ©βπ§βπ¦");
print("π©π»βπ€βπ§πΏ");
print("πΊπ¦");
use the code: 'text'.split('').map(e=>{return e.charCodeAt(0).toString(2)}) e.g.-
const text='some text';
const output=text.split('').map(e=>{return e.charCodeAt(0).toString(2)})
Simple using Buffer
const text = "TEST";
[...Buffer.from(text).values()] // [ 84, 69, 83, 84 ]
.map(byte => byte.toString(2).padStart(8, 0)) // [ '01010100', '01000101', '01010011', '01010100' ]
.join(' ') // '01010100 01000101 01010011 01010100'
The shortest and simplest solution:
"x".charCodeAt().toString(2) // 1111000
String.charCodeAt() charCodeAt(0) returns unicode: "x".charCodeAt() // 120
Object.toString() charCodeAt().toString(2) converts unicode to binary.
For multiple string characters:
[..."Tesla"].map((i) => i.charCodeAt().toString(2)).join(" ");
// 1010100 1100101 1110011 1101100 1100001
Spread syntax (...)
[..."Tesla"] // ['T', 'e', 's', 'l', 'a']
Array.map()
[..."Tesla"].map((i) => i.charCodeAt()) // [84, 101, 115, 108, 97]
Array.join() Put a space " " after each element in the array map(i) and convert the array to string.
I'm pretty sure that you can do something like this:
Returns a STRING:
const toBinary = (str)=>{
let r = []
for (let i=0; i<str.length; i++) {
r.push(str.charCodeAt(i).toString(2));
}
return r.join("");
}
Or, as an int:
const toBinary = (str)=>{
let r = []
for (let i=0; i<str.length; i++) {
r.push(str.charCodeAt(i).toString(2));
}
return parseInt(r.join(""));
}
the list looks like:
3434,346,1,6,46
How can I append a number to it with javascript, but only if it doesn't already exist in it?
Assuming your initial value is a string (you didn't say).
var listOfNumbers = '3434,346,1,6,46', add = 34332;
var numbers = listOfNumbers.split(',');
if(numbers.indexOf(add)!=-1) {
numbers.push(add);
}
listOfNumbers = numbers.join(',');
Basically i convert the string into an array, check the existence of the value using indexOf(), adding only if it doesn't exist.
I then convert the value back to a string using join.
If that is a string, you can use the .split() and .join() functions, as well as .push():
var data = '3434,346,1,6,46';
var arr = data.split(',');
var add = newInt;
arr.push(newInt);
data = arr.join(',');
If that is already an array, you can just use .push():
var data = [3434,346,1,6,46];
var add = newInt;
data.push(add);
UPDATE: Didn't read the last line to check for duplicates, the best approach I can think of is a loop:
var data = [3434,346,1,6,46];
var add = newInt;
var exists = false;
for (var i = 0; i < input.length; i++) {
if (data[i] == add) {
exists = true;
break;
}
}
if (!exists) {
data.push(add);
// then you would join if you wanted a string
}
You can also use a regular expression:
function appendConditional(s, n) {
var re = new RegExp('(^|\\b)' + n + '(\\b|$)');
if (!re.test(s)) {
return s + (s.length? ',' : '') + n;
}
return s;
}
var nums = '3434,346,1,6,46'
alert( appendConditional(nums, '12') ); // '3434,346,1,6,46,12'
alert( appendConditional(nums, '6') ); // '3434,346,1,6,46'
Oh, since some really like ternary operators and obfustically short code:
function appendConditional(s, n) {
var re = new RegExp('(^|\\b)' + n + '(\\b|$)');
return s + (re.test(s)? '' : (''+s? ',':'') + n );
}
No jQuery, "shims" or cross-browser issues. :-)