encodeURIComponent algorithm source code - javascript

I am developing an application in titanium using Javascript. I need an open source implementation of encodeURIComponent in Javascript.
Can anybody guide me or show me some implementation?

The specification for this function is in 15.1.3.4.
Modern versions (2018) of V8 implement it in C++. See src/uri.h:
// ES6 section 18.2.6.5 encodeURIComponenet (uriComponent)
static MaybeHandle<String> EncodeUriComponent(Isolate* isolate,
Handle<String> component) {
which calls into Encode defined in uri.cc.
Older versions of V8 implemented it in JavaScript and distributed under the BSD license. See line 359 of src/uri.js.
// ECMA-262 - 15.1.3.4
function URIEncodeComponent(component) {
var unescapePredicate = function(cc) {
if (isAlphaNumeric(cc)) return true;
// !
if (cc == 33) return true;
// '()*
if (39 <= cc && cc <= 42) return true;
// -.
if (45 <= cc && cc <= 46) return true;
// _
if (cc == 95) return true;
// ~
if (cc == 126) return true;
return false;
};
var string = ToString(component);
return Encode(string, unescapePredicate);
}
It's not called encodeURIComponent there, but this code in the same file, esablishes the mapping:
InstallFunctions(global, DONT_ENUM, $Array(
"escape", URIEscape,
"unescape", URIUnescape,
"decodeURI", URIDecode,
"decodeURIComponent", URIDecodeComponent,
"encodeURI", URIEncode,
"encodeURIComponent", URIEncodeComponent
));

Here is my implementation:
var encodeURIComponent = function( str ) {
var hexDigits = '0123456789ABCDEF';
var ret = '';
for( var i=0; i<str.length; i++ ) {
var c = str.charCodeAt(i);
if( (c >= 48/*0*/ && c <= 57/*9*/) ||
(c >= 97/*a*/ && c <= 122/*z*/) ||
(c >= 65/*A*/ && c <= 90/*Z*/) ||
c == 45/*-*/ || c == 95/*_*/ || c == 46/*.*/ || c == 33/*!*/ || c == 126/*~*/ ||
c == 42/***/ || c == 92/*\\*/ || c == 40/*(*/ || c == 41/*)*/ ) {
ret += str[i];
}
else {
ret += '%';
ret += hexDigits[ (c & 0xF0) >> 4 ];
ret += hexDigits[ (c & 0x0F) ];
}
}
return ret;
};

What for do you need encodeuricomponent? It is already present in JS.
Anyway, here's an example of implementation:
http://phpjs.org/functions/rawurlencode:501#comment_93984

Related

Number Formatting for large integer numbers in Javascript

I know there are in-build function in javascript like toLocalString() to achieve number formatting. But this question is purely for learning and logic understanding.
I have a function in javascript that formats given number in Indian Number formatting standards (eg: 1,234 | 12,21,123 | etc)
Code
function formatter(input) {
var inputStr = input.toString(), l = inputStr.length;
var c = 1, f = 0;
console.log(l);
for (var x=l-1; x>=0; x--) {
if (x === 0) {
continue;
}
if (c === 3 && f === 0) {
inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x);
f = 1;
c = 0;
} else if (c % 2 === 0 && f === 1) {
inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x);
c = 0;
}
c++;
}
return inputStr;
}
Now this works for most part (as far as I have test, do point out bugs if you spot any). But my question is how do I handle large number in this, i.e. how do I handle values greater than 9007199254740991.
Hope this now fixes the issue:
function formatter(inputStr) {
inputStr+="";
let c = 1, f = 0;
for (let x=inputStr.length-1; x>=0; x--) {
if (x === 0) continue;
if (c === 3 && f === 0) {
inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x);
f = 1;
c = 0;
} else if (c % 2 === 0 && f === 1) {
inputStr = inputStr.substring(0, x) + ',' + inputStr.substring(x);
c = 0;
}
c++;
}
return inputStr;
}
//========= Tests =======
console.log(formatter(9007199254740991));
console.log(formatter("900719925474093454549341"));
console.log(formatter("123456678890987665443221112345667676766545434243"));

While loop runs forever in JavaScript

I've writen a function in JavaScript that checks through all the combinations of three digits between 1 and 9 and gives me the number of combinations that follow this pattern
√(x^2 + y^2 + z^2) = a natural number (a full number like 24 or 34 but not 2.54)
√ = square root , ^2 = to the power of 2,
My problem is that whenever I run the function the computer gets stuck and the function never ends so it doesn't return an answer.
I would very much appreciate if someone could tell me whats wrong with it
(I'm running my programs on the chrome browser console)
function mmd() {
var chk = false;
var a = 1;
var b = 1;
var c = 1;
var d = 1;
var e = 0;
while(chk != true) {
d = Math.sqrt(Math.pow(a, 2)+Math.pow(b, 2)+Math.pow(c, 2));
if( d == d.toFixed(0)) {
e++;
}
else {
if((b == 9) && (a == 9) && (c == 9)) {chk = true;}
else if((a == 9) && (b == 9)) {c++;}
else if(b == 9) {b = 1; a++;}
else if(c == 9) {c = 1; b++;}
else if(c < 9) {c++;}
}
}
return e
}
This part of the code is causing it to never end:
if (d == d.toFixed(0)){} else {}
If the result of the formula is an integer, you add 1 to e, but you don't increment the other variables, because of the else. It keeps doing e++ for ever. So you need to remove that else.
I also took the liberty or removing that chk variable, and instead used while(true), which will be ended by a return of the final result:
function mmd() {
var a = 1, b = 1, c = 1, d, e = 0;
while(true) {
d = Math.sqrt(Math.pow(a, 2)+Math.pow(b, 2)+Math.pow(c, 2));
if( d == parseInt(d, 10)) {
e++;
}
if((b == 9) && (a == 9) && (c == 9)) {return e;}
else if((a == 9) && (b == 9)) {c++;}
else if(b == 9) {b = 1; a++;}
else if(c == 9) {c = 1; b++;}
else {c++;}
}
}
alert(mmd());
It gets stuck once it hits the e++ block and never increases a, b, or c.
function mmd()
{
var keepGoing = true;
var a = 1, b = 1, c = 1, d, e = 0;
while(keepGoing)
{
// calculate d
d = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2) + Math.pow(c, 2));
// check if it is a whole number
if(d == d.toFixed(0)) e++;
// if we're done then stop
if(a == 9 && b == 9 && c == 9){ keepGoing = false; }
// if c is less than 9 then increase it
else if(c < 9){ c++; }
// if c is 9 and b is less than 9 then set c back to 1 and increase b
else if(b < 9){ c = 1; b++; }
// if c is 9 and b is 9 then set both back to 1 and increase a
else if(a < 9){ c = b = 1; a++; }
}
return e;
}

Strange use of "for" cycle in Javascript, please explain

I found this strange JavaScript I cannot understand. The for cycle has a strange syntax (many parameters), can you explain me how it is intended to work? Thanks
decode: function(s){
for(var a, b, i = -1, l = (s = s.split("")).length, o = String.fromCharCode, c = "charCodeAt"; ++i < l;
((a = s[i][c](0)) & 0x80) &&
(s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ?
o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "")
);
return s.join("");
}
That's an ordinary for loop, but with a very long var statement in the first part.
It's just like
var a, b, c;
Also the iterator statement in the for loop contains a lot of operations instead of the loop actually having a body.
Either this function was written by a terrible programmer with no regard for readable code, or it has been intentionally minified and obfuscated.
interesting function, apparently trans-coding a certain set of chars, kind of esoteric and will only work with an ASCII code but here's the breakdown:
for (var i = 0; i < s.length; i++) {
var a = s.charCodeAt(i);
if (a & 0x80) { // (a >= 128) if extended ascii
var b = s.charCodeAt(i + 1);
var specialA = (a & 0xfc) === 0xc0; // a IS [À, Á, Â or Ã] essentially [192, 193, 194, 195]
var specialB = (b & 0xc0) === 0x80; // b >= 128 & b <= 191 eg. b is not a special Latin Ascii Letter
if (specialA && specialB) {
var txA = (a & 0x03) << 6; // [0, 64, 128, 192]
var txB = b & 0x3f; // 0 - 63
s[i] = String.fromCharCode(txA + txB);
} else {
s[i] = String.fromCharCode(128);
s[++i] = "";
}
}
}
hope this helps, either way i found the decoding interesting, reminds of reading raw assembler, lol -ck
The different parts of the for loop is all there, divided by the semicolons (;).
The var part:
var a, b, i = -1, l = (s = s.split("")).length, o = String.fromCharCode, c = "charCodeAt";
The check part:
++i < l;
The update part:
((a = s[i][c](0)) & 0x80) &&
(s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ?
o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "")
After the for() statement comes a ; right away, meaning that the loop doesn't have a body, but all the statements in the var-, check-, and update part will still be executed untill the check is no longer true.
Looks like someone didn't want their code to be readable. Where did you find it, anyway?
Breaking the loop into a one more readable:
rearranged loop parameters
changed (...)&&(...) with an if(...){(...)}
changed l to len
moved s = s.split(...) outside the len
.
var a, b, s = s.split(""), o = String.fromCharCode, c = "charCodeAt";
for(var i = -1, len = s.length; ++i < len;){
if((a = s[i][c](0)) & 0x80){
(s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ? o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "");
}
}
changed i initial value and how/where it increases
moved a = s[i][c](0) outside
.
var a, b, s = s.split(""), o = String.fromCharCode, c = "charCodeAt";
for(var i = 0, len = s.length; i < len; i++){
a = s[i][c](0);
if(a & 0x80){
s[i] = (a & 0xfc);
(s[i] == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ? o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "");
}
}
created tmp to make things easier to read
stored the ternary operation result in tmp
splitted (s[i] == 0xc0 && tmp, s[++i] = ""); with an
if(...){s[++i] = "";}
replaced the new loop inside the your example
.
decode: function(s){
var tmp, a, b, s = s.split(""), o = String.fromCharCode, c = "charCodeAt";
for(var i = 0, len = s.length; i < len; i++){
a = s[i][c](0);
if(a & 0x80){
s[i] = (a & 0xfc);
if(((b = s[i + 1][c](0)) & 0xc0) == 0x80){
tmp = o(((a & 0x03) << 6) + (b & 0x3f));
}else{
tmp = o(128);
}
if(s[i] == 0xc0 && tmp){
s[++i] = "";
}
}
}
return s.join("");
}
Final result /\

How to trim document.getElementbyId value in JavaScript? [duplicate]

JavaScript doesn't seem to have a native trim() method. How can I trim white spaces at the start and end of a string with JavaScript?
The shortest form for jQuery:
string = $.trim(string);
Link
according to this page the best all-around approach is
return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
Of course if you are using jQuery , it will provide you with an optimized trim method.
I know this question is ancient but now, Javascript actually does have a native .trim()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
Well, as a lot of people always says, the trim function works pretty well, but if you don't want to use a whole framework just to perform a trim, it may be useful to take a look at its implementation. So here it is:
function( text ) { return (text || "").replace( /^(\s|\u00A0)+|(\s|\u00A0)+$/g, "" );}
The main advantages I see in this implementation, comparing to other solution already proposed here are:
The 'g' flag that allows you to perfom a trim on a multi-line string
The (text || "") syntax that ensure that the function will always work, even if the argument passed is null or undefined.
As a couple of others have already noted, it's usually best to do this sort of thing by using a third-party JS library. Not that trim() is a complicated function to build yourself, but there are so many functions that aren't native to JavaScript that you might need and end-up writing yourself, it soon becomes more cost-effective to use a library.
Of course, another advantage of using a JS library is that the authors do the hard work of ensuring that the functions work across all the major browsers, so that you can code to a standard interface and forget about the irritating differences between Internet Explorer and all the other browsers.
A slightly tinier version of #Pat's.
return str.replace( /^\s+|\s+$/g, '' );
For ltrim, replace spaces anchored at the start of the string with nothing:
str2 = str.replace(/^\s+/,'');
For rtrim, replace spaces anchored at the end of the string with nothing:
str2 = str.replace(/\s+$/,'');
For trim:
str2 = str.replace(/^\s+|\s+$/g,'');
These all use regex'es to do the actual work.
Why not just modify the String prototype? Why not steal the trim function from an open source library, like I did here with YUI? (Do you really need to load and entire framework for this simple taks?) Put them together and you get this:
String.prototype.trim = function() {
try {
return this.replace(/^\s+|\s+$/g, "");
} catch(e) {
return this;
}
}
var s = " hello ";
alert(s.trim() == "hello"); // displays true
Use Ariel Flesler's fast trim function:
// Licensed under BSD
function myBestTrim( str ){
var start = -1,
end = str.length;
while( str.charCodeAt(--end) < 33 );
while( str.charCodeAt(++start) < 33 );
return str.slice( start, end + 1 );
};
My solution, though, would be this (because the String object in Firefox 3.5 and above already has a trim method):
String.prototype.trim = String.prototype.trim || function () {
var start = -1,
end = this.length;
while( this.charCodeAt(--end) < 33 );
while( this.charCodeAt(++start) < 33 );
return this.slice( start, end + 1 );
};
I made a trim-function speed in mind. This function beats in a clear difference all of 24 competitors (of which many use regular expressions) and also native string.trim() of Chrome and Chromium(!) and performs as speedy as Safari's trim(). Test results are here: http://jsperf.com/mega-trim-test/7
function trim27(str) {
var c;
for (var i = 0; i < str.length; i++) {
c = str.charCodeAt(i);
if (c == 32 || c == 10 || c == 13 || c == 9 || c == 12)
continue; else break;
}
for (var j = str.length - 1; j >= i; j--) {
c = str.charCodeAt(j);
if (c == 32 || c == 10 || c == 13 || c == 9 || c == 12)
continue; else break;
}
return str.substring(i, j + 1);
}
The function trims characters " \n\r\t\f", but it's easy to add more whitespace-characters, eg. those that regexp uses as whitespaces (\s) with only a minor performance lost ( please see http://jsperf.com/mega-trim-test/8 ).
Edit: The previous trim27() trims only the most common characters (" \n\r\t\f"), but to trim all possible whitespaces, I included below a new function mytrim():
if (!String.prototype.trim || "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF".trim() || navigator.userAgent.toString().toLowerCase().indexOf("chrome") != -1)
var mytrim = function(str) {
var c;
for (var i = 0; i < str.length; i++) {
c = str.charCodeAt(i);
if (c == 32 || c == 10 || c == 13 || c == 9 || c == 12 || c == 11 || c == 160 || c == 5760 || c == 6158 || c == 8192 || c == 8193 || c == 8194 || c == 8195 || c == 8196 || c == 8197 || c == 8198 || c == 8199 || c == 8200 || c == 8201 || c == 8202 || c == 8232 || c == 8233 || c == 8239 || c == 8287 || c == 12288 || c == 65279)
continue; else break;
}
for (var j = str.length - 1; j >= i; j--) {
c = str.charCodeAt(j);
if (c == 32 || c == 10 || c == 13 || c == 9 || c == 12 || c == 11 || c == 160 || c == 5760 || c == 6158 || c == 8192 || c == 8193 || c == 8194 || c == 8195 || c == 8196 || c == 8197 || c == 8198 || c == 8199 || c == 8200 || c == 8201 || c == 8202 || c == 8232 || c == 8233 || c == 8239 || c == 8287 || c == 12288 || c == 65279)
continue; else break;
}
return str.substring(i, j + 1);
};
else var mytrim = function(str) {
return str.trim();
}
Use it this way:
var foo = mytrim(" \n \t Trimmed \f \n "); // foo is now "Trimmed"
The above mytrim() does the following:
Trims 26 different whitespaces (all of 25 whitespaces mentioned in http://perfectionkills.com/whitespace-deviations/ and additionally uFEFF, which is ZERO WIDTH NO-BREAK SPACE.
Makes trimming results consistent across browsers.
Uses native trim() if it is available AND has ability to trim all of 27 different whitespaces. The exception is Chrome and Chromium which both have so slow native trim() that instead of native we use our custom trim.
AND THE MOST IMPORTANT: Is not beautiful and is not short, but IS CLEARLY FASTER than any of the 24 competitive alternatives in http://jsperf.com/mega-trim-test/12 (exception: rather old Firefox 3.6.25 in Windows 7 runs mytrim() rather slowly for unknown reason).
I use this with native JavaScript
// Adding trim function to String object if its not there
if(typeof String.prototype.trim !== 'function') {
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, '');
}
}
Use like this
var myString = " some text ";
alert(myString.trim());
Example
// Adding trim function to String object if its not there
if(typeof String.prototype.trim !== 'function') {
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, '');
}
}
var str = " some text ";
console.log(str.trim());
The answer to so many JavaScript questions: jQuery
$j.trim(string)
Note: the above assumes your jQuery has been setup with:
<script type="text/javascript">$j = jQuery.noConflict();</script>
Which is far more sensible than "$", and far less verbose than typing "jQuery" every time.
Microsoft .NET also has String.trim function as a part of JavaScript Base Type Extensions. It could be used if you are coding ASP.NET application.
I use this.
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g,"");
}
Actually, with jQuery this seems to be the way:
jQuery.trim(string)
(Reference)
I use this:
Work with functions.
function trim($) {
return (typeof $ == "function" ? $() : $).replace(/[\s]*/g,"")
}
code example:
trim((function(){ return "a b"})) // ab
trim(" a b") //ab
This is probably not the fastest, and might violate what ".trim()" probably should really be, but I don't like RegExs (mainly because it takes so much time to figure out what they really mean/do) and I like having something that I know will work regardless of whether I have jQuery or not (not to mention the right version, since I tried $.trim(myVar) with jQuery 1.4.2 and it does not work), and will get rid of ALL extra spaces, not just at the end, rebuilding it like it should be:
function Trim(obj) {
var coll = "";
var arrObj = obj.split(' ');
for (var i=0;i<arrObj.length;i++) {
if (arrObj[i] == "") {
arrObj.splice(i,1); // removes array indices containing spaces
}
}
//alert(arrObj.length); // should be equal to the number of words
// Rebuilds with spaces in-between words, but without spaces at the end
for (var i=0;i<arrObj.length;i++) {
if (arrObj[i] != "" && i != arrObj.length-1)
coll += arrObj[i] + " ";
if (arrObj[i] != "" && i == arrObj.length-1)
coll += arrObj[i];
}
return coll;
}
This is an old question but none of these worked for me. I just needed to trim leading and trailing white space and this is what I did. My div tag had an id = start-date.
$("#start-date").text().trim()
You can use following ...
function trim(str) {
try {
if (str && typeof(str) == 'string') {
return str.replace(/^\s*|\s*$/g, "");
} else {
return '';
}
} catch (e) {
return str;
}
}

How do you reverse a string in-place in JavaScript?

How do you reverse a string in-place in JavaScript when it is passed to a function with a return statement, without using built-in functions (.reverse(), .charAt() etc.)?
As long as you're dealing with simple ASCII characters, and you're happy to use built-in functions, this will work:
function reverse(s){
return s.split("").reverse().join("");
}
If you need a solution that supports UTF-16 or other multi-byte characters, be aware that this function will give invalid unicode strings, or valid strings that look funny. You might want to consider this answer instead.
[...s] is Unicode aware, a small edit gives:-
function reverse(s){
return [...s].reverse().join("");
}
The following technique (or similar) is commonly used to reverse a string in JavaScript:
// Don’t use this!
var naiveReverse = function(string) {
return string.split('').reverse().join('');
}
In fact, all the answers posted so far are a variation of this pattern. However, there are some problems with this solution. For example:
naiveReverse('foo 𝌆 bar');
// → 'rab �� oof'
// Where did the `𝌆` symbol go? Whoops!
If you’re wondering why this happens, read up on JavaScript’s internal character encoding. (TL;DR: 𝌆 is an astral symbol, and JavaScript exposes it as two separate code units.)
But there’s more:
// To see which symbols are being used here, check:
// http://mothereff.in/js-escapes#1ma%C3%B1ana%20man%CC%83ana
naiveReverse('mañana mañana');
// → 'anãnam anañam'
// Wait, so now the tilde is applied to the `a` instead of the `n`? WAT.
A good string to test string reverse implementations is the following:
'foo 𝌆 bar mañana mañana'
Why? Because it contains an astral symbol (𝌆) (which are represented by surrogate pairs in JavaScript) and a combining mark (the ñ in the last mañana actually consists of two symbols: U+006E LATIN SMALL LETTER N and U+0303 COMBINING TILDE).
The order in which surrogate pairs appear cannot be reversed, else the astral symbol won’t show up anymore in the ‘reversed’ string. That’s why you saw those �� marks in the output for the previous example.
Combining marks always get applied to the previous symbol, so you have to treat both the main symbol (U+006E LATIN SMALL LETTER N) as the combining mark (U+0303 COMBINING TILDE) as a whole. Reversing their order will cause the combining mark to be paired with another symbol in the string. That’s why the example output had ã instead of ñ.
Hopefully, this explains why all the answers posted so far are wrong.
To answer your initial question — how to [properly] reverse a string in JavaScript —, I’ve written a small JavaScript library that is capable of Unicode-aware string reversal. It doesn’t have any of the issues I just mentioned. The library is called Esrever; its code is on GitHub, and it works in pretty much any JavaScript environment. It comes with a shell utility/binary, so you can easily reverse strings from your terminal if you want.
var input = 'foo 𝌆 bar mañana mañana';
esrever.reverse(input);
// → 'anañam anañam rab 𝌆 oof'
As for the “in-place” part, see the other answers.
String.prototype.reverse_string=function() {return this.split("").reverse().join("");}
or
String.prototype.reverse_string = function() {
var s = "";
var i = this.length;
while (i>0) {
s += this.substring(i-1,i);
i--;
}
return s;
}
Detailed analysis and ten different ways to reverse a string and their performance details.
http://eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript/
Perfomance of these implementations:
Best performing implementation(s) per browser
Chrome 15 - Implemations 1 and 6
Firefox 7 - Implementation 6
IE 9 - Implementation 4
Opera 12 - Implementation 9
Here are those implementations:
Implementation 1:
function reverse(s) {
var o = '';
for (var i = s.length - 1; i >= 0; i--)
o += s[i];
return o;
}
Implementation 2:
function reverse(s) {
var o = [];
for (var i = s.length - 1, j = 0; i >= 0; i--, j++)
o[j] = s[i];
return o.join('');
}
Implementation 3:
function reverse(s) {
var o = [];
for (var i = 0, len = s.length; i <= len; i++)
o.push(s.charAt(len - i));
return o.join('');
}
Implementation 4:
function reverse(s) {
return s.split('').reverse().join('');
}
Implementation 5:
function reverse(s) {
var i = s.length,
o = '';
while (i > 0) {
o += s.substring(i - 1, i);
i--;
}
return o;
}
Implementation 6:
function reverse(s) {
for (var i = s.length - 1, o = ''; i >= 0; o += s[i--]) { }
return o;
}
Implementation 7:
function reverse(s) {
return (s === '') ? '' : reverse(s.substr(1)) + s.charAt(0);
}
Implementation 8:
function reverse(s) {
function rev(s, len, o) {
return (len === 0) ? o : rev(s, --len, (o += s[len]));
};
return rev(s, s.length, '');
}
Implementation 9:
function reverse(s) {
s = s.split('');
var len = s.length,
halfIndex = Math.floor(len / 2) - 1,
tmp;
for (var i = 0; i <= halfIndex; i++) {
tmp = s[len - i - 1];
s[len - i - 1] = s[i];
s[i] = tmp;
}
return s.join('');
}
Implementation 10
function reverse(s) {
if (s.length < 2)
return s;
var halfIndex = Math.ceil(s.length / 2);
return reverse(s.substr(halfIndex)) +
reverse(s.substr(0, halfIndex));
}
Implementation 11
var reverser = function(str){
let string = str.split('');
for(i=0;i<string.length;i++){
debugger;
string.splice(i,0,string.pop());
}
console.log(string.join())
}
reverser('abcdef')
The whole "reverse a string in place" is an antiquated interview question C programmers, and people who were interviewed by them (for revenge, maybe?), will ask. Unfortunately, it's the "In Place" part that no longer works because strings in pretty much any managed language (JS, C#, etc) uses immutable strings, thus defeating the whole idea of moving a string without allocating any new memory.
While the solutions above do indeed reverse a string, they do not do it without allocating more memory, and thus do not satisfy the conditions. You need to have direct access to the string as allocated, and be able to manipulate its original memory location to be able to reverse it in place.
Personally, i really hate these kinds of interview questions, but sadly, i'm sure we'll keep seeing them for years to come.
First, use Array.from() to turn a string into an array, then Array.prototype.reverse() to reverse the array, and then Array.prototype.join() to make it back a string.
const reverse = str => Array.from(str).reverse().join('');
In ECMAScript 6, you can reverse a string even faster without using .split('') split method, with the spread operator like so:
var str = [...'racecar'].reverse().join('');
Seems like I'm 3 years late to the party...
Unfortunately you can't as has been pointed out. See Are JavaScript strings immutable? Do I need a "string builder" in JavaScript?
The next best thing you can do is to create a "view" or "wrapper", which takes a string and reimplements whatever parts of the string API you are using, but pretending the string is reversed. For example:
var identity = function(x){return x};
function LazyString(s) {
this.original = s;
this.length = s.length;
this.start = 0; this.stop = this.length; this.dir = 1; // "virtual" slicing
// (dir=-1 if reversed)
this._caseTransform = identity;
}
// syntactic sugar to create new object:
function S(s) {
return new LazyString(s);
}
//We now implement a `"...".reversed` which toggles a flag which will change our math:
(function(){ // begin anonymous scope
var x = LazyString.prototype;
// Addition to the String API
x.reversed = function() {
var s = new LazyString(this.original);
s.start = this.stop - this.dir;
s.stop = this.start - this.dir;
s.dir = -1*this.dir;
s.length = this.length;
s._caseTransform = this._caseTransform;
return s;
}
//We also override string coercion for some extra versatility (not really necessary):
// OVERRIDE STRING COERCION
// - for string concatenation e.g. "abc"+reversed("abc")
x.toString = function() {
if (typeof this._realized == 'undefined') { // cached, to avoid recalculation
this._realized = this.dir==1 ?
this.original.slice(this.start,this.stop) :
this.original.slice(this.stop+1,this.start+1).split("").reverse().join("");
this._realized = this._caseTransform.call(this._realized, this._realized);
}
return this._realized;
}
//Now we reimplement the String API by doing some math:
// String API:
// Do some math to figure out which character we really want
x.charAt = function(i) {
return this.slice(i, i+1).toString();
}
x.charCodeAt = function(i) {
    return this.slice(i, i+1).toString().charCodeAt(0);
}
// Slicing functions:
x.slice = function(start,stop) {
// lazy chaining version of https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/slice
if (stop===undefined)
stop = this.length;
var relativeStart = start<0 ? this.length+start : start;
var relativeStop = stop<0 ? this.length+stop : stop;
if (relativeStart >= this.length)
relativeStart = this.length;
if (relativeStart < 0)
relativeStart = 0;
if (relativeStop > this.length)
relativeStop = this.length;
if (relativeStop < 0)
relativeStop = 0;
if (relativeStop < relativeStart)
relativeStop = relativeStart;
var s = new LazyString(this.original);
s.length = relativeStop - relativeStart;
s.start = this.start + this.dir*relativeStart;
s.stop = s.start + this.dir*s.length;
s.dir = this.dir;
//console.log([this.start,this.stop,this.dir,this.length], [s.start,s.stop,s.dir,s.length])
s._caseTransform = this._caseTransform;
return s;
}
x.substring = function() {
// ...
}
x.substr = function() {
// ...
}
//Miscellaneous functions:
// Iterative search
x.indexOf = function(value) {
for(var i=0; i<this.length; i++)
if (value==this.charAt(i))
return i;
return -1;
}
x.lastIndexOf = function() {
for(var i=this.length-1; i>=0; i--)
if (value==this.charAt(i))
return i;
return -1;
}
// The following functions are too complicated to reimplement easily.
// Instead just realize the slice and do it the usual non-in-place way.
x.match = function() {
var s = this.toString();
return s.apply(s, arguments);
}
x.replace = function() {
var s = this.toString();
return s.apply(s, arguments);
}
x.search = function() {
var s = this.toString();
return s.apply(s, arguments);
}
x.split = function() {
var s = this.toString();
return s.apply(s, arguments);
}
// Case transforms:
x.toLowerCase = function() {
var s = new LazyString(this.original);
s._caseTransform = ''.toLowerCase;
s.start=this.start; s.stop=this.stop; s.dir=this.dir; s.length=this.length;
return s;
}
x.toUpperCase = function() {
var s = new LazyString(this.original);
s._caseTransform = ''.toUpperCase;
s.start=this.start; s.stop=this.stop; s.dir=this.dir; s.length=this.length;
return s;
}
})() // end anonymous scope
Demo:
> r = S('abcABC')
LazyString
original: "abcABC"
__proto__: LazyString
> r.charAt(1); // doesn't reverse string!!! (good if very long)
"B"
> r.toLowerCase() // must reverse string, so does so
"cbacba"
> r.toUpperCase() // string already reversed: no extra work
"CBACBA"
> r + '-demo-' + r // natural coercion, string already reversed: no extra work
"CBAcba-demo-CBAcba"
The kicker -- the following is done in-place by pure math, visiting each character only once, and only if necessary:
> 'demo: ' + S('0123456789abcdef').slice(3).reversed().slice(1,-1).toUpperCase()
"demo: EDCBA987654"
> S('0123456789ABCDEF').slice(3).reversed().slice(1,-1).toLowerCase().charAt(3)
"b"
This yields significant savings if applied to a very large string, if you are only taking a relatively small slice thereof.
Whether this is worth it (over reversing-as-a-copy like in most programming languages) highly depends on your use case and how efficiently you reimplement the string API. For example if all you want is to do string index manipulation, or take small slices or substrs, this will save you space and time. If you're planning on printing large reversed slices or substrings however, the savings may be small indeed, even worse than having done a full copy. Your "reversed" string will also not have the type string, though you might be able to fake this with prototyping.
The above demo implementation creates a new object of type ReversedString. It is prototyped, and therefore fairly efficient, with almost minimal work and minimal space overhead (prototype definitions are shared). It is a lazy implementation involving deferred slicing. Whenever you perform a function like .slice or .reversed, it will perform index mathematics. Finally when you extract data (by implicitly calling .toString() or .charCodeAt(...) or something), it will apply those in a "smart" manner, touching the least data possible.
Note: the above string API is an example, and may not be implemented perfectly. You also can use just 1-2 functions which you need.
Legible way using spread syntax:
const reverseString = str => [...str].reverse().join('');
console.log(reverseString('ABC'));
There are many ways you can reverse a string in JavaScript. I'm jotting down three ways I prefer.
Approach 1: Using reverse function:
function reverse(str) {
return str.split('').reverse().join('');
}
Approach 2: Looping through characters:
function reverse(str) {
let reversed = '';
for (let character of str) {
reversed = character + reversed;
}
return reversed;
}
Approach 3: Using reduce function:
function reverse(str) {
return str.split('').reduce((rev, char) => char + rev, '');
}
I hope this helps :)
There are Multiple ways of doing it, you may check the following,
1. Traditional for loop(incrementing):
function reverseString(str){
let stringRev ="";
for(let i= 0; i<str.length; i++){
stringRev = str[i]+stringRev;
}
return stringRev;
}
alert(reverseString("Hello World!"));
2. Traditional for loop(decrementing):
function reverseString(str){
let revstr = "";
for(let i = str.length-1; i>=0; i--){
revstr = revstr+ str[i];
}
return revstr;
}
alert(reverseString("Hello World!"));
3. Using for-of loop
function reverseString(str){
let strn ="";
for(let char of str){
strn = char + strn;
}
return strn;
}
alert(reverseString("Get well soon"));
4. Using the forEach/ high order array method:
function reverseString(str){
let revSrring = "";
str.split("").forEach(function(char){
revSrring = char + revSrring;
});
return revSrring;
}
alert(reverseString("Learning JavaScript"));
5. ES6 standard:
function reverseString(str){
let revSrring = "";
str.split("").forEach(char => revSrring = char + revSrring);
return revSrring;
}
alert(reverseString("Learning JavaScript"));
6. The latest way:
function reverseString(str){
return str.split("").reduce(function(revString, char){
return char + revString;
}, "");
}
alert(reverseString("Learning JavaScript"));
7. You may also get the result using the following,
function reverseString(str){
return str.split("").reduce((revString, char)=> char + revString, "");
}
alert(reverseString("Learning JavaScript"));
During an interview, I was asked to reverse a string without using any variables or native methods. This is my favorite implementation:
function reverseString(str) {
return str === '' ? '' : reverseString(str.slice(1)) + str[0];
}
In ES6, you have one more option
function reverseString (str) {
return [...str].reverse().join('')
}
reverseString('Hello');
This is the easiest way I think
var reverse = function(str) {
var arr = [];
for (var i = 0, len = str.length; i <= len; i++) {
arr.push(str.charAt(len - i))
}
return arr.join('');
}
console.log(reverse('I want a 🍺'));
var str = 'sample string';
[].map.call(str, function(x) {
return x;
}).reverse().join('');
OR
var str = 'sample string';
console.log(str.split('').reverse().join(''));
// Output: 'gnirts elpmas'
If you don't want to use any built in function. Try this
var string = 'abcdefg';
var newstring = '';
for(let i = 0; i < string.length; i++){
newstring = string[i] += newstring;
}
console.log(newstring);
I know that this is an old question that has been well answered, but for my own amusement I wrote the following reverse function and thought I would share it in case it was useful for anyone else. It handles both surrogate pairs and combining marks:
function StringReverse (str)
{
var charArray = [];
for (var i = 0; i < str.length; i++)
{
if (i+1 < str.length)
{
var value = str.charCodeAt(i);
var nextValue = str.charCodeAt(i+1);
if ( ( value >= 0xD800 && value <= 0xDBFF
&& (nextValue & 0xFC00) == 0xDC00) // Surrogate pair)
|| (nextValue >= 0x0300 && nextValue <= 0x036F)) // Combining marks
{
charArray.unshift(str.substring(i, i+2));
i++; // Skip the other half
continue;
}
}
// Otherwise we just have a rogue surrogate marker or a plain old character.
charArray.unshift(str[i]);
}
return charArray.join('');
}
All props to Mathias, Punycode, and various other references for schooling me on the complexities of character encoding in JavaScript.
You can't because JS strings are immutable. Short non-in-place solution
[...str].reverse().join``
let str = "Hello World!";
let r = [...str].reverse().join``;
console.log(r);
You can't reverse a string in place but you can use this:
String.prototype.reverse = function() {
return this.split("").reverse().join("");
}
var s = "ABCD";
s = s.reverse();
console.log(s);
One new option is to use Intl.Segmenter which allows you to split on the visual graphemes (ie: user-perceived character units such as emojis, characters, etc.). Intl.Segmenter is currently a stage 4 proposal and there is a polyfill available for it if you wish to use it. It currently has limited browser support which you can find more information about here.
Here is how the reverse() method may look if you use Intl.Segmenter:
const reverse = str => {
const segmenter = new Intl.Segmenter("en", {granularity: 'grapheme'});
const segitr = segmenter.segment(str);
const segarr = Array.from(segitr, ({segment}) => segment).reverse();
return segarr.join('');
}
console.log(reverse('foo 𝌆 bar mañana mañana')); // anañam anañam rab 𝌆 oof
console.log(reverse('This 😊 emoji is happy')); // yppah si ijome 😊 sihT
console.log(reverse('Text surrogate pair 𝌆 composite pair möo varient selector ❤️ & ZWJ 👨‍👩‍👦')); // 👨‍👩‍👦 JWZ & ❤️ rotceles tneirav oöm riap etisopmoc 𝌆 riap etagorrus txeT
The above creates a segmenter to segment/split strings by their visual graphemes. Calling .segment() on the segmenter with the string input then returns an iterator, which produces objects of the form {segment, index, input, isWordLike}. The segment key from this object contains the string segment (ie: the individual grapheme). To convert the iterator to an array, we use Array.from() on the iterator and extract the segmented graphemes, which can be reversed with .reverse(). Lastly, we join the array back into a string using .join()
There is also another option which you can try that has better browser support than Intl.Segmenter, however isn't as bullet-proof:
const reverse = str => Array.from(str.normalize('NFC')).reverse().join('');
this helps deal with characters consisting of multiple code points and code units. As pointed out in other answers, there are issues with maintaining composite and surrogate pair ordering in strings such as 'foo 𝌆 bar mañana mañana'. Here 𝌆 is a surrogate pair consisting of two code units, and the last ñ is a composite pair consisting of two Unicode characters to make up one grapheme (n+̃ = ñ).
In order to reverse each character, you can use the .reverse() method which is part of the Array prototype. As .reverse() is used on an array, the first thing to do is to turn the string into an array of characters. Typically, .split('') is used for this task, however, this splits up surrogate pairs which are made from up of multiple code units (as already shown in previous answers):
>> '𝌆'.split('')
>> `["�", "�"]`
Instead, if you invoke the String.prototype's Symbol.iterator method then you'll be able to retain your surrogate pairs within your array, as this iterates over the code points rather than the code units of your string:
>> [...'𝌆']
>> ["𝌆"]
The next thing to handle is any composite characters within the string. Characters that consist of two or more code points will still be split when iterated on:
>> [...'ö']
>> ["o", "̈"]
The above separates the base character (o) from the diaresis, which is not desired behavior. This is because ö is a decomposed version of the character, consisting of multiple code points. To deal with this, you can use a string method introduced in ES6 known as String.prototype.normalize(). This method can compose multiple code points into its composed canonical form by using "NFC" as an argument. This allows us to convert the decomposed character ö (o + combining diaeresis) into its precomposed form ö (latin small letter o with diaeresis) which consists of only one code point. Calling .normalize() with "NFC" thus tries to replace multiple code points with single code points where possible. This allows graphemes consisting of two code points to be represented with one code point.
>> [...'ö'.normalize('NFC')]
>> ["ö"]
As normalize('NFC') produces one character, it can then be reversed safely when amongst others. Putting both the spread syntax and normalization together, you can successfully reverse strings of characters such as:
const reverse = str => Array.from(str.normalize('NFC')).reverse().join('');
console.log(reverse('foo 𝌆 bar mañana mañana'));
console.log(reverse('This 😊 emoji is happy'));
There are a few cases where the above normalization+iteration will fail. For instance, the character ❤️ (heavy black heart ❤️) consists of two code points. The first being the heart and the latter being the variation selector-16 (U+FE0F) which is used to define a glyph variant for the preceding character. Other characters can also produce similar issues like this.
Another thing to look out for is ZWJ (Zero-width joiner) characters, which you can find in some scripts, including emoji. For example the emoji 👨‍👩‍👦 comprises of the Man, Woman and Boy emoji, each separated by a ZWJ. The above normalization + iteration method will not account for this either.
As a result, using Intl.Segmenter is the better choice over these two approaches. Currently, Chrome also has its own specific segmentation API known as Intl.v8BreakIterator. This segmentation API is nonstandard and something that Chrome simply just implements. So, it is subject to change and doesn't work on most browsers, so it's not recommended to use. However, if you're curious, this is how it could be done:
const reverse = str => {
const iterator = Intl.v8BreakIterator(['en'], {type: 'character'});
iterator.adoptText(str);
const arr = [];
let pos = iterator.first();
while (pos !== -1) {
const current = iterator.current();
const nextPos = iterator.next();
if (nextPos === -1) break;
const slice = str.slice(current, nextPos);
arr.unshift(slice);
}
return arr.join("");
}
console.log(reverse('foo 𝌆 bar mañana mañana')); // anañam anañam rab 𝌆 oof
console.log(reverse('This 😊 emoji is happy')); // yppah si ijome 😊 sihT
console.log(reverse('Text surrogate pair 𝌆 composite pair möo varient selector ❤️ & ZWJ 👨‍👩‍👦')); // 👨‍👩‍👦 JWZ & ❤️ rotceles tneirav oöm riap etisopmoc 𝌆 riap etagorrus txeT
UTF-8 strings can have:
Combining diacritics such as b̃ which composed of the b character and a following ~ diacritic generated by the unicode escape sequnce \u0303;
Multi-byte characters such as 🎥; which is generated by the multi-byte unicode escape sequence \uD83C\uDFA5; and
Multiple characters may be combined together with a zero-width joiner character (given by the unicode escape sequence \u200D). For example, the character 👨‍👩‍👦 can be composed using the individual (multi-byte) emojis 👨 then a zero-width joiner then 👩 then another zero-width joiner then 👦 such that the entire 3-person character is 8-bytes (\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC66).
This will handle reversing all 3 cases and keeping the bytes in the correct order such that the characters are reversed (rather than naively reversing the bytes of the string):
(function(){
var isCombiningDiacritic = function( code )
{
return (0x0300 <= code && code <= 0x036F) // Comb. Diacritical Marks
|| (0x1AB0 <= code && code <= 0x1AFF) // Comb. Diacritical Marks Extended
|| (0x1DC0 <= code && code <= 0x1DFF) // Comb. Diacritical Marks Supplement
|| (0x20D0 <= code && code <= 0x20FF) // Comb. Diacritical Marks for Symbols
|| (0xFE20 <= code && code <= 0xFE2F); // Comb. Half Marks
};
String.prototype.reverse = function()
{
let output = "";
for ( let i = this.length; i > 0; )
{
let width = 0;
let has_zero_width_joiner = false;
while( i > 0 && isCombiningDiacritic( this.charCodeAt(i-1) ) )
{
--i;
width++;
}
do {
--i;
width++;
if (
i > 0
&& "\uDC00" <= this[i] && this[i] <= "\uDFFF"
&& "\uD800" <= this[i-1] && this[i-1] <= "\uDBFF"
)
{
--i;
width++;
}
has_zero_width_joiner = i > 0 && "\u200D" == this[i-1];
if ( has_zero_width_joiner )
{
--i;
width++;
}
}
while( i > 0 && has_zero_width_joiner );
output += this.substr( i, width );
}
return output;
}
})();
// Tests
[
'abcdefg',
'ab\u0303c',
'a\uD83C\uDFA5b',
'a\uD83C\uDFA5b\uD83C\uDFA6c',
'a\uD83C\uDFA5b\u0306c\uD83C\uDFA6d',
'TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚​N̐Y̡', // copied from http://stackoverflow.com/a/1732454/1509264
'What 👨‍👩‍👦 is this?'
].forEach(
function(str){ console.log( str + " -> " + str.reverse() ); }
);
Update
The above code identifies some of the more commonly used combining diacritics. A more complete list of combining diacritics (that could be swapped into the above code) is:
var isCombiningDiacritic = function( code )
{
return (0x0300 <= code && code <= 0x036F)
|| (0x0483 <= code && code <= 0x0489)
|| (0x0591 <= code && code <= 0x05BD)
|| (code == 0x05BF)
|| (0x05C1 <= code && code <= 0x05C2)
|| (0x05C4 <= code && code <= 0x05C5)
|| (code == 0x05C7)
|| (0x0610 <= code && code <= 0x061A)
|| (0x064B <= code && code <= 0x065F)
|| (code == 0x0670)
|| (0x06D6 <= code && code <= 0x06DC)
|| (0x06DF <= code && code <= 0x06E4)
|| (0x06E7 <= code && code <= 0x06E8)
|| (0x06EA <= code && code <= 0x06ED)
|| (code == 0x0711)
|| (0x0730 <= code && code <= 0x074A)
|| (0x07A6 <= code && code <= 0x07B0)
|| (0x07EB <= code && code <= 0x07F3)
|| (code == 0x07FD)
|| (0x0816 <= code && code <= 0x0819)
|| (0x081B <= code && code <= 0x0823)
|| (0x0825 <= code && code <= 0x0827)
|| (0x0829 <= code && code <= 0x082D)
|| (0x0859 <= code && code <= 0x085B)
|| (0x08D3 <= code && code <= 0x08E1)
|| (0x08E3 <= code && code <= 0x0902)
|| (code == 0x093A)
|| (code == 0x093C)
|| (0x0941 <= code && code <= 0x0948)
|| (code == 0x094D)
|| (0x0951 <= code && code <= 0x0957)
|| (0x0962 <= code && code <= 0x0963)
|| (code == 0x0981)
|| (code == 0x09BC)
|| (0x09C1 <= code && code <= 0x09C4)
|| (code == 0x09CD)
|| (0x09E2 <= code && code <= 0x09E3)
|| (0x09FE <= code && code <= 0x0A02)
|| (code == 0x0A3C)
|| (0x0A41 <= code && code <= 0x0A51)
|| (0x0A70 <= code && code <= 0x0A71)
|| (code == 0x0A75)
|| (0x0A81 <= code && code <= 0x0A82)
|| (code == 0x0ABC)
|| (0x0AC1 <= code && code <= 0x0AC8)
|| (code == 0x0ACD)
|| (0x0AE2 <= code && code <= 0x0AE3)
|| (0x0AFA <= code && code <= 0x0B01)
|| (code == 0x0B3C)
|| (code == 0x0B3F)
|| (0x0B41 <= code && code <= 0x0B44)
|| (0x0B4D <= code && code <= 0x0B56)
|| (0x0B62 <= code && code <= 0x0B63)
|| (code == 0x0B82)
|| (code == 0x0BC0)
|| (code == 0x0BCD)
|| (code == 0x0C00)
|| (code == 0x0C04)
|| (0x0C3E <= code && code <= 0x0C40)
|| (0x0C46 <= code && code <= 0x0C56)
|| (0x0C62 <= code && code <= 0x0C63)
|| (code == 0x0C81)
|| (code == 0x0CBC)
|| (0x0CCC <= code && code <= 0x0CCD)
|| (0x0CE2 <= code && code <= 0x0CE3)
|| (0x0D00 <= code && code <= 0x0D01)
|| (0x0D3B <= code && code <= 0x0D3C)
|| (0x0D41 <= code && code <= 0x0D44)
|| (code == 0x0D4D)
|| (0x0D62 <= code && code <= 0x0D63)
|| (code == 0x0DCA)
|| (0x0DD2 <= code && code <= 0x0DD6)
|| (code == 0x0E31)
|| (0x0E34 <= code && code <= 0x0E3A)
|| (0x0E47 <= code && code <= 0x0E4E)
|| (code == 0x0EB1)
|| (0x0EB4 <= code && code <= 0x0EBC)
|| (0x0EC8 <= code && code <= 0x0ECD)
|| (0x0F18 <= code && code <= 0x0F19)
|| (code == 0x0F35)
|| (code == 0x0F37)
|| (code == 0x0F39)
|| (0x0F71 <= code && code <= 0x0F7E)
|| (0x0F80 <= code && code <= 0x0F84)
|| (0x0F86 <= code && code <= 0x0F87)
|| (0x0F8D <= code && code <= 0x0FBC)
|| (code == 0x0FC6)
|| (0x102D <= code && code <= 0x1030)
|| (0x1032 <= code && code <= 0x1037)
|| (0x1039 <= code && code <= 0x103A)
|| (0x103D <= code && code <= 0x103E)
|| (0x1058 <= code && code <= 0x1059)
|| (0x105E <= code && code <= 0x1060)
|| (0x1071 <= code && code <= 0x1074)
|| (code == 0x1082)
|| (0x1085 <= code && code <= 0x1086)
|| (code == 0x108D)
|| (code == 0x109D)
|| (0x135D <= code && code <= 0x135F)
|| (0x1712 <= code && code <= 0x1714)
|| (0x1732 <= code && code <= 0x1734)
|| (0x1752 <= code && code <= 0x1753)
|| (0x1772 <= code && code <= 0x1773)
|| (0x17B4 <= code && code <= 0x17B5)
|| (0x17B7 <= code && code <= 0x17BD)
|| (code == 0x17C6)
|| (0x17C9 <= code && code <= 0x17D3)
|| (code == 0x17DD)
|| (0x180B <= code && code <= 0x180D)
|| (0x1885 <= code && code <= 0x1886)
|| (code == 0x18A9)
|| (0x1920 <= code && code <= 0x1922)
|| (0x1927 <= code && code <= 0x1928)
|| (code == 0x1932)
|| (0x1939 <= code && code <= 0x193B)
|| (0x1A17 <= code && code <= 0x1A18)
|| (code == 0x1A1B)
|| (code == 0x1A56)
|| (0x1A58 <= code && code <= 0x1A60)
|| (code == 0x1A62)
|| (0x1A65 <= code && code <= 0x1A6C)
|| (0x1A73 <= code && code <= 0x1A7F)
|| (0x1AB0 <= code && code <= 0x1B03)
|| (code == 0x1B34)
|| (0x1B36 <= code && code <= 0x1B3A)
|| (code == 0x1B3C)
|| (code == 0x1B42)
|| (0x1B6B <= code && code <= 0x1B73)
|| (0x1B80 <= code && code <= 0x1B81)
|| (0x1BA2 <= code && code <= 0x1BA5)
|| (0x1BA8 <= code && code <= 0x1BA9)
|| (0x1BAB <= code && code <= 0x1BAD)
|| (code == 0x1BE6)
|| (0x1BE8 <= code && code <= 0x1BE9)
|| (code == 0x1BED)
|| (0x1BEF <= code && code <= 0x1BF1)
|| (0x1C2C <= code && code <= 0x1C33)
|| (0x1C36 <= code && code <= 0x1C37)
|| (0x1CD0 <= code && code <= 0x1CD2)
|| (0x1CD4 <= code && code <= 0x1CE0)
|| (0x1CE2 <= code && code <= 0x1CE8)
|| (code == 0x1CED)
|| (code == 0x1CF4)
|| (0x1CF8 <= code && code <= 0x1CF9)
|| (0x1DC0 <= code && code <= 0x1DFF)
|| (0x20D0 <= code && code <= 0x20F0)
|| (0x2CEF <= code && code <= 0x2CF1)
|| (code == 0x2D7F)
|| (0x2DE0 <= code && code <= 0x2DFF)
|| (0x302A <= code && code <= 0x302D)
|| (0x3099 <= code && code <= 0x309A)
|| (0xA66F <= code && code <= 0xA672)
|| (0xA674 <= code && code <= 0xA67D)
|| (0xA69E <= code && code <= 0xA69F)
|| (0xA6F0 <= code && code <= 0xA6F1)
|| (code == 0xA802)
|| (code == 0xA806)
|| (code == 0xA80B)
|| (0xA825 <= code && code <= 0xA826)
|| (0xA8C4 <= code && code <= 0xA8C5)
|| (0xA8E0 <= code && code <= 0xA8F1)
|| (code == 0xA8FF)
|| (0xA926 <= code && code <= 0xA92D)
|| (0xA947 <= code && code <= 0xA951)
|| (0xA980 <= code && code <= 0xA982)
|| (code == 0xA9B3)
|| (0xA9B6 <= code && code <= 0xA9B9)
|| (0xA9BC <= code && code <= 0xA9BD)
|| (code == 0xA9E5)
|| (0xAA29 <= code && code <= 0xAA2E)
|| (0xAA31 <= code && code <= 0xAA32)
|| (0xAA35 <= code && code <= 0xAA36)
|| (code == 0xAA43)
|| (code == 0xAA4C)
|| (code == 0xAA7C)
|| (code == 0xAAB0)
|| (0xAAB2 <= code && code <= 0xAAB4)
|| (0xAAB7 <= code && code <= 0xAAB8)
|| (0xAABE <= code && code <= 0xAABF)
|| (code == 0xAAC1)
|| (0xAAEC <= code && code <= 0xAAED)
|| (code == 0xAAF6)
|| (code == 0xABE5)
|| (code == 0xABE8)
|| (code == 0xABED)
|| (code == 0xFB1E)
|| (0xFE00 <= code && code <= 0xFE0F)
|| (0xFE20 <= code && code <= 0xFE2F)
|| (code == 0x101FD)
|| (code == 0x102E0)
|| (0x10376 <= code && code <= 0x1037A)
|| (0x10A01 <= code && code <= 0x10A0F)
|| (0x10A38 <= code && code <= 0x10A3F)
|| (0x10AE5 <= code && code <= 0x10AE6)
|| (0x10D24 <= code && code <= 0x10D27)
|| (0x10F46 <= code && code <= 0x10F50)
|| (code == 0x11001)
|| (0x11038 <= code && code <= 0x11046)
|| (0x1107F <= code && code <= 0x11081)
|| (0x110B3 <= code && code <= 0x110B6)
|| (0x110B9 <= code && code <= 0x110BA)
|| (0x11100 <= code && code <= 0x11102)
|| (0x11127 <= code && code <= 0x1112B)
|| (0x1112D <= code && code <= 0x11134)
|| (code == 0x11173)
|| (0x11180 <= code && code <= 0x11181)
|| (0x111B6 <= code && code <= 0x111BE)
|| (0x111C9 <= code && code <= 0x111CC)
|| (0x1122F <= code && code <= 0x11231)
|| (code == 0x11234)
|| (0x11236 <= code && code <= 0x11237)
|| (code == 0x1123E)
|| (code == 0x112DF)
|| (0x112E3 <= code && code <= 0x112EA)
|| (0x11300 <= code && code <= 0x11301)
|| (0x1133B <= code && code <= 0x1133C)
|| (code == 0x11340)
|| (0x11366 <= code && code <= 0x11374)
|| (0x11438 <= code && code <= 0x1143F)
|| (0x11442 <= code && code <= 0x11444)
|| (code == 0x11446)
|| (code == 0x1145E)
|| (0x114B3 <= code && code <= 0x114B8)
|| (code == 0x114BA)
|| (0x114BF <= code && code <= 0x114C0)
|| (0x114C2 <= code && code <= 0x114C3)
|| (0x115B2 <= code && code <= 0x115B5)
|| (0x115BC <= code && code <= 0x115BD)
|| (0x115BF <= code && code <= 0x115C0)
|| (0x115DC <= code && code <= 0x115DD)
|| (0x11633 <= code && code <= 0x1163A)
|| (code == 0x1163D)
|| (0x1163F <= code && code <= 0x11640)
|| (code == 0x116AB)
|| (code == 0x116AD)
|| (0x116B0 <= code && code <= 0x116B5)
|| (code == 0x116B7)
|| (0x1171D <= code && code <= 0x1171F)
|| (0x11722 <= code && code <= 0x11725)
|| (0x11727 <= code && code <= 0x1172B)
|| (0x1182F <= code && code <= 0x11837)
|| (0x11839 <= code && code <= 0x1183A)
|| (0x119D4 <= code && code <= 0x119DB)
|| (code == 0x119E0)
|| (0x11A01 <= code && code <= 0x11A06)
|| (0x11A09 <= code && code <= 0x11A0A)
|| (0x11A33 <= code && code <= 0x11A38)
|| (0x11A3B <= code && code <= 0x11A3E)
|| (code == 0x11A47)
|| (0x11A51 <= code && code <= 0x11A56)
|| (0x11A59 <= code && code <= 0x11A5B)
|| (0x11A8A <= code && code <= 0x11A96)
|| (0x11A98 <= code && code <= 0x11A99)
|| (0x11C30 <= code && code <= 0x11C3D)
|| (0x11C92 <= code && code <= 0x11CA7)
|| (0x11CAA <= code && code <= 0x11CB0)
|| (0x11CB2 <= code && code <= 0x11CB3)
|| (0x11CB5 <= code && code <= 0x11CB6)
|| (0x11D31 <= code && code <= 0x11D45)
|| (code == 0x11D47)
|| (0x11D90 <= code && code <= 0x11D91)
|| (code == 0x11D95)
|| (code == 0x11D97)
|| (0x11EF3 <= code && code <= 0x11EF4)
|| (0x16AF0 <= code && code <= 0x16AF4)
|| (0x16B30 <= code && code <= 0x16B36)
|| (code == 0x16F4F)
|| (0x16F8F <= code && code <= 0x16F92)
|| (0x1BC9D <= code && code <= 0x1BC9E)
|| (0x1D167 <= code && code <= 0x1D169)
|| (0x1D17B <= code && code <= 0x1D182)
|| (0x1D185 <= code && code <= 0x1D18B)
|| (0x1D1AA <= code && code <= 0x1D1AD)
|| (0x1D242 <= code && code <= 0x1D244)
|| (0x1DA00 <= code && code <= 0x1DA36)
|| (0x1DA3B <= code && code <= 0x1DA6C)
|| (code == 0x1DA75)
|| (code == 0x1DA84)
|| (0x1DA9B <= code && code <= 0x1E02A)
|| (0x1E130 <= code && code <= 0x1E136)
|| (0x1E2EC <= code && code <= 0x1E2EF)
|| (0x1E8D0 <= code && code <= 0x1E8D6)
|| (0x1E944 <= code && code <= 0x1E94A)
|| (0xE0100 <= code && code <= 0xE01EF);
};
function reverseString(string) {
var reversedString = "";
var stringLength = string.length - 1;
for (var i = stringLength; i >= 0; i--) {
reversedString += string[i];
}
return reversedString;
}
I think String.prototype.reverse is a good way to solve this problem;
the code as below;
String.prototype.reverse = function() {
return this.split('').reverse().join('');
}
var str = 'this is a good example for string reverse';
str.reverse();
-> "esrever gnirts rof elpmaxe doog a si siht";
The real answer is: you can't reverse it in place, but you can create a new string that is the reverse.
Just as an exercise to play with recursion: sometimes when you go to an interview, the interviewer may ask you how to do this using recursion, and I think the "preferred answer" might be "I would rather not do this in recursion as it can easily cause a stack overflow" (because it is O(n) rather than O(log n). If it is O(log n), it is quite difficult to get a stack overflow -- 4 billion items could be handled by a stack level of 32, as 2 ** 32 is 4294967296. But if it is O(n), then it can easily get a stack overflow.
Sometimes the interviewer will still ask you, "just as an exercise, why don't you still write it using recursion?" And here it is:
String.prototype.reverse = function() {
if (this.length <= 1) return this;
else return this.slice(1).reverse() + this.slice(0,1);
}
test run:
var s = "";
for(var i = 0; i < 1000; i++) {
s += ("apple" + i);
}
console.log(s.reverse());
output:
999elppa899elppa...2elppa1elppa0elppa
To try getting a stack overflow, I changed 1000 to 10000 in Google Chrome, and it reported:
RangeError: Maximum call stack size exceeded
Strings themselves are immutable, but you can easily create a reversed copy with the following code:
function reverseString(str) {
var strArray = str.split("");
strArray.reverse();
var strReverse = strArray.join("");
return strReverse;
}
reverseString("hello");
//es6
//array.from
const reverseString = (string) => Array.from(string).reduce((a, e) => e + a);
//split
const reverseString = (string) => string.split('').reduce((a, e) => e + a);
//split problem
"𠜎𠺢".split('')[0] === Array.from("𠜎𠺢")[0] // "�" === "𠜎" => false
"😂😹🤗".split('')[0] === Array.from("😂😹🤗")[0] // "�" === "😂" => false
Reverse a String using built-in functions
function reverse(str) {
// Use the split() method to return a new array
// Use the reverse() method to reverse the new created array
// Use the join() method to join all elements of the array into a string
return str.split("").reverse().join("");
}
console.log(reverse('hello'));
Reverse a String without the helpers
function reversedOf(str) {
let newStr = '';
for (let char of str) {
newStr = char + newStr
// 1st round: "h" + "" = h, 2nd round: "e" + "h" = "eh" ... etc.
// console.log(newStr);
}
return newStr;
}
console.log(reversedOf('hello'));
Using Array functions,
String.prototype.reverse = function(){
return [].reduceRight.call(this, function(last, secLast){return last + secLast});
}
var str = "my name is saurabh ";
var empStr='',finalString='';
var chunk=[];
function reverse(str){
var i,j=0,n=str.length;
for(i=0;i<n;++i){
if(str[i]===' '){
chunk[j]=empStr;
empStr = '';
j++;
}else{
empStr=empStr+str[i];
}
}
for(var z=chunk.length-1;z>=0;z--){
finalString = finalString +' '+ chunk[z];
console.log(finalString);
}
return true;
}
reverse(str);
My own original attempt...
var str = "The Car";
function reverseStr(str) {
var reversed = "";
var len = str.length;
for (var i = 1; i < (len + 1); i++) {
reversed += str[len - i];
}
return reversed;
}
var strReverse = reverseStr(str);
console.log(strReverse);
// "raC ehT"
http://jsbin.com/bujiwo/19/edit?js,console,output

Categories