Wie umkehren Sie eine Zeichenfolge an Ort und Stelle (oder in-place) in JavaScript , wenn es um eine Funktion mit einer return - Anweisung übergeben wird, ohne Einbau-Verwendung von Funktionen ( .reverse()
, .charAt()
etc.)?
Wie umkehren Sie eine Zeichenfolge an Ort und Stelle (oder in-place) in JavaScript , wenn es um eine Funktion mit einer return - Anweisung übergeben wird, ohne Einbau-Verwendung von Funktionen ( .reverse()
, .charAt()
etc.)?
Antworten:
Solange Sie mit einfachen ASCII-Zeichen arbeiten und gerne integrierte Funktionen verwenden, funktioniert dies:
function reverse(s){
return s.split("").reverse().join("");
}
Wenn Sie eine Lösung benötigen, die UTF-16 oder andere Multi-Byte-Zeichen unterstützt, beachten Sie, dass diese Funktion ungültige Unicode-Zeichenfolgen oder gültige Zeichenfolgen liefert, die lustig aussehen. Vielleicht möchten Sie stattdessen diese Antwort berücksichtigen .
[... s] ist Unicode-fähig, eine kleine Bearbeitung ergibt: -
function reverse(s){
return [...s].reverse().join("");
}
return [...s].reverse().join("");
kann funktionieren.
Die folgende Technik (oder eine ähnliche) wird üblicherweise verwendet, um eine Zeichenfolge in JavaScript umzukehren:
// Don’t use this!
var naiveReverse = function(string) {
return string.split('').reverse().join('');
}
Tatsächlich sind alle bisher veröffentlichten Antworten eine Variation dieses Musters. Es gibt jedoch einige Probleme mit dieser Lösung. Zum Beispiel:
naiveReverse('foo 𝌆 bar');
// → 'rab �� oof'
// Where did the `𝌆` symbol go? Whoops!
Wenn Sie sich fragen, warum dies passiert, lesen Sie die interne Zeichenkodierung von JavaScript . (TL; DR: 𝌆
ist ein Astralsymbol und wird von JavaScript als zwei separate Codeeinheiten verfügbar gemacht.)
Aber es gibt noch mehr:
// 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.
Ein guter String zum Testen von String-Reverse-Implementierungen ist der folgende :
'foo 𝌆 bar mañana mañana'
Warum? Weil es ein Astralsymbol ( 𝌆
) (das in JavaScript durch Ersatzpaare dargestellt wird ) und eine Kombinationsmarke enthält (die ñ
letzte mañana
besteht tatsächlich aus zwei Symbolen: U + 006E LATIN SMALL LETTER N und U + 0303 COMBINING TILDE).
Die Reihenfolge, in der Ersatzpaare erscheinen, kann nicht umgekehrt werden, da sonst das Astralsymbol nicht mehr in der "umgekehrten" Zeichenfolge angezeigt wird. Aus diesem Grund haben Sie diese ��
Markierungen in der Ausgabe des vorherigen Beispiels gesehen.
Kombinationsmarken werden immer auf das vorherige Symbol angewendet, daher müssen Sie sowohl das Hauptsymbol (U + 006E LATIN SMALL LETTER N) als die Kombinationsmarke (U + 0303 COMBINING TILDE) als Ganzes behandeln. Durch Umkehren der Reihenfolge wird die Kombinationsmarke mit einem anderen Symbol in der Zeichenfolge gepaart. Deshalb hatte die Beispielausgabe ã
statt ñ
.
Hoffentlich erklärt dies, warum alle bisher veröffentlichten Antworten falsch sind .
Um Ihre erste Frage zu beantworten - wie man eine Zeichenfolge in JavaScript [richtig] umkehrt - habe ich eine kleine JavaScript-Bibliothek geschrieben, die eine Unicode-fähige Zeichenfolgenumkehr ermöglicht. Es hat keine der Probleme, die ich gerade erwähnt habe. Die Bibliothek heißt Esrever ; Der Code befindet sich auf GitHub und funktioniert in nahezu jeder JavaScript-Umgebung. Es wird mit einem Shell-Dienstprogramm / einer Binärdatei geliefert, sodass Sie Zeichenfolgen von Ihrem Terminal aus problemlos umkehren können, wenn Sie möchten.
var input = 'foo 𝌆 bar mañana mañana';
esrever.reverse(input);
// → 'anañam anañam rab 𝌆 oof'
Weitere Informationen zum „In-Place“ -Teil finden Sie in den anderen Antworten.
String.prototype.reverse_string=function() {return this.split("").reverse().join("");}
oder
String.prototype.reverse_string = function() {
var s = "";
var i = this.length;
while (i>0) {
s += this.substring(i-1,i);
i--;
}
return s;
}
Detaillierte Analyse und zehn verschiedene Möglichkeiten zum Umkehren einer Zeichenfolge und ihrer Leistungsdetails.
http://eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript/
Leistung dieser Implementierungen:
Implementierung (en) mit der besten Leistung pro Browser
Hier sind diese Implementierungen:
Implementierung 1:
function reverse(s) {
var o = '';
for (var i = s.length - 1; i >= 0; i--)
o += s[i];
return o;
}
Implementierung 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('');
}
Implementierung 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('');
}
Implementierung 4:
function reverse(s) {
return s.split('').reverse().join('');
}
Implementierung 5:
function reverse(s) {
var i = s.length,
o = '';
while (i > 0) {
o += s.substring(i - 1, i);
i--;
}
return o;
}
Implementierung 6:
function reverse(s) {
for (var i = s.length - 1, o = ''; i >= 0; o += s[i--]) { }
return o;
}
Implementierung 7:
function reverse(s) {
return (s === '') ? '' : reverse(s.substr(1)) + s.charAt(0);
}
Implementierung 8:
function reverse(s) {
function rev(s, len, o) {
return (len === 0) ? o : rev(s, --len, (o += s[len]));
};
return rev(s, s.length, '');
}
Implementierung 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('');
}
Implementierung 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));
}
Das ganze "Reverse a String in Place" ist eine veraltete Interviewfrage, die C-Programmierer und Leute, die von ihnen interviewt wurden (vielleicht aus Rache?), Fragen werden. Leider funktioniert der Teil "An Ort und Stelle" nicht mehr, da Zeichenfolgen in nahezu jeder verwalteten Sprache (JS, C # usw.) unveränderliche Zeichenfolgen verwenden, wodurch die gesamte Idee, eine Zeichenfolge zu verschieben, ohne neuen Speicher zuzuweisen, zunichte gemacht wird.
Während die obigen Lösungen tatsächlich eine Zeichenfolge umkehren, tun sie dies nicht, ohne mehr Speicher zuzuweisen, und erfüllen daher nicht die Bedingungen. Sie müssen direkten Zugriff auf die zugewiesene Zeichenfolge haben und in der Lage sein, ihren ursprünglichen Speicherort zu ändern, um sie an Ort und Stelle umkehren zu können.
Persönlich hasse ich solche Interviewfragen wirklich, aber leider bin ich mir sicher, dass wir sie noch viele Jahre sehen werden.
Verwenden Sie zuerst Array.from()
, um eine Zeichenfolge in ein Array umzuwandeln, dann Array.prototype.reverse()
um das Array umzukehren und es dann Array.prototype.join()
wieder zu einer Zeichenfolge zu machen.
const reverse = str => Array.from(str).reverse().join('');
reverse
Logik wird nicht umgeschrieben .
string.split('')
funktioniert nicht. Weitere Erklärungen finden Sie in dieser Antwort .
Array.from('foo 𝌆 bar mañana mañana').reverse().join('') == 'anãnam anañam rab 𝌆 oof'
Array.from('foo 𝌆 bar mañana mañana'.normalize('NFC')).reverse().join('')
wird"anañam anañam rab 𝌆 oof"
In ECMAScript 6 können Sie eine Zeichenfolge noch schneller umkehren, ohne die .split('')
Split-Methode zu verwenden. Der Spread-Operator lautet wie folgt:
var str = [...'racecar'].reverse().join('');
string.split('')
ist für die meisten Menschen klarer als [...string]
.
.split('')
hat das Problem mit Zeichen aus den Zusatzebenen (Surrogatpaar in UTF-16), da sie von der UTF-16 - Code teilt Einheit anstatt Codepunkt . Der Spread-Operator und Array.from()
(meine Präferenz) nicht.
Scheint, als wäre ich 3 Jahre zu spät zur Party ...
Leider können Sie nicht, wie bereits erwähnt wurde. Siehe Sind JavaScript-Zeichenfolgen unveränderlich? Benötige ich einen "String Builder" in JavaScript?
Das nächstbeste, was Sie tun können, ist, eine "Ansicht" oder einen "Wrapper" zu erstellen, der eine Zeichenfolge verwendet und alle Teile der von Ihnen verwendeten Zeichenfolgen-API neu implementiert, aber so tut, als wäre die Zeichenfolge umgekehrt. Zum Beispiel:
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"
Der Kicker - Folgendes wird vor Ort durch reine Mathematik erledigt, wobei jeder Charakter nur einmal und nur bei Bedarf besucht wird:
> 'demo: ' + S('0123456789abcdef').slice(3).reversed().slice(1,-1).toUpperCase()
"demo: EDCBA987654"
> S('0123456789ABCDEF').slice(3).reversed().slice(1,-1).toLowerCase().charAt(3)
"b"
Dies führt zu erheblichen Einsparungen, wenn Sie auf eine sehr große Zeichenfolge angewendet werden, wenn Sie nur eine relativ kleine Scheibe davon nehmen.
Ob sich dies lohnt (über das Umkehren als Kopie wie in den meisten Programmiersprachen), hängt stark von Ihrem Anwendungsfall ab und davon, wie effizient Sie die Zeichenfolgen-API erneut implementieren. Wenn Sie beispielsweise nur einen String-Index bearbeiten oder kleine slice
s oder substr
s nehmen möchten , sparen Sie Platz und Zeit. Wenn Sie jedoch große umgekehrte Schnitte oder Teilzeichenfolgen drucken möchten, sind die Einsparungen möglicherweise gering und sogar noch schlimmer als bei einer vollständigen Kopie. Ihre "umgekehrte" Zeichenfolge hat auch nicht den Typstring
, obwohl Sie dies möglicherweise mit Prototyping vortäuschen können.
Die obige Demo-Implementierung erstellt ein neues Objekt vom Typ ReversedString. Es ist ein Prototyp und daher ziemlich effizient mit nahezu minimalem Arbeitsaufwand und minimalem Platzaufwand (Prototypdefinitionen werden gemeinsam genutzt). Es ist eine träge Implementierung, die ein verzögertes Schneiden beinhaltet. Wann immer Sie eine Funktion wie .slice
oder .reversed
ausführen, wird eine Indexmathematik ausgeführt. Schließlich, wenn Sie Daten extrahieren (indem Sie implizit .toString()
oder aufrufen.charCodeAt(...)
etwas anderes), werden diese auf "intelligente" Weise angewendet, wobei die geringstmöglichen Daten berührt werden.
Hinweis: Die obige Zeichenfolgen-API ist ein Beispiel und möglicherweise nicht perfekt implementiert. Sie können auch nur 1-2 Funktionen verwenden, die Sie benötigen.
Es gibt viele Möglichkeiten, wie Sie eine Zeichenfolge in JavaScript umkehren können. Ich schreibe drei Möglichkeiten auf, die ich bevorzuge.
Ansatz 1: Umkehrfunktion verwenden:
function reverse(str) {
return str.split('').reverse().join('');
}
Ansatz 2: Durchlaufen von Charakteren:
function reverse(str) {
let reversed = '';
for (let character of str) {
reversed = character + reversed;
}
return reversed;
}
Ansatz 3: Verwenden der Reduktionsfunktion:
function reverse(str) {
return str.split('').reduce((rev, char) => char + rev, '');
}
Ich hoffe das hilft :)
Während eines Interviews wurde ich gebeten, eine Zeichenfolge ohne Verwendung von Variablen oder nativen Methoden umzukehren. Dies ist meine Lieblingsimplementierung:
function reverseString(str) {
return str === '' ? '' : reverseString(str.slice(1)) + str[0];
}
slice
? : - /
Array.prototype.reverse()
.
Es gibt mehrere Möglichkeiten, dies zu tun. Sie können Folgendes überprüfen:
1. Traditionell für Schleife (Inkrementieren):
function reverseString(str){
let stringRev ="";
for(let i= 0; i<str.length; i++){
stringRev = str[i]+stringRev;
}
return stringRev;
}
alert(reverseString("Hello World!"));
2. Traditionell für Schleife (Dekrementierung):
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. Verwenden der for-of-Schleife
function reverseString(str){
let strn ="";
for(let char of str){
strn = char + strn;
}
return strn;
}
alert(reverseString("Get well soon"));
4. Verwenden der forEach / Array-Methode höherer Ordnung:
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. Der neueste Weg:
function reverseString(str){
return str.split("").reduce(function(revString, char){
return char + revString;
}, "");
}
alert(reverseString("Learning JavaScript"));
7. Sie können das Ergebnis auch wie folgt erhalten:
function reverseString(str){
return str.split("").reduce((revString, char)=> char + revString, "");
}
alert(reverseString("Learning JavaScript"));
In ES6 haben Sie noch eine Option
function reverseString (str) {
return [...str].reverse().join('')
}
reverseString('Hello');
Dies ist der einfachste Weg, den ich denke
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 🍺'));
Array.prototype.reverse()
dies am einfachsten, daher die beliebteste Antwort. Natürlich würde es gute Vorkenntnisse in JavaScript erfordern.
Ich weiß, dass dies eine alte Frage ist, die gut beantwortet wurde, aber zu meiner eigenen Unterhaltung habe ich die folgende Umkehrfunktion geschrieben und dachte, ich würde sie teilen, falls sie für andere nützlich wäre. Es behandelt sowohl Ersatzpaare als auch Kombinationsmarken:
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('');
}
Alle Requisiten an Mathias, Punycode und verschiedene andere Referenzen, um mich über die Komplexität der Zeichenkodierung in JavaScript zu unterrichten.
Sie können nicht, weil JS-Zeichenfolgen unveränderlich sind. Kurze Non-In-Place-Lösung
[...str].reverse().join``
Wenn Sie keine eingebaute Funktion verwenden möchten. Versuche dies
var string = 'abcdefg';
var newstring = '';
for(let i = 0; i < string.length; i++){
newstring = string[i] += newstring;
}
console.log(newstring);
Die eigentliche Antwort lautet: Sie können es nicht an Ort und Stelle umkehren, aber Sie können eine neue Zeichenfolge erstellen, die umgekehrt ist.
Nur als Übung, um mit Rekursion zu spielen: Manchmal, wenn Sie zu einem Interview gehen, fragt Sie der Interviewer, wie Sie dies mit Rekursion tun sollen, und ich denke, die "bevorzugte Antwort" könnte lauten: "Ich würde dies lieber nicht in Rekursion tun, wie es ist." kann leicht einen Stapelüberlauf verursachen "(weil dies O(n)
nicht der Fall ist O(log n)
. Wenn dies O(log n)
der Fall ist , ist es ziemlich schwierig, einen Stapelüberlauf zu erhalten - 4 Milliarden Elemente könnten von einer Stapelstufe von 32 verarbeitet werden, da 2 ** 32 4294967296 ist. Aber wenn es so istO(n)
Fall , kann es leicht zu einem Stapelüberlauf kommen.
Manchmal fragt Sie der Interviewer immer noch: "Nur als Übung, warum schreiben Sie sie nicht immer noch mit Rekursion?" Und hier ist es:
String.prototype.reverse = function() {
if (this.length <= 1) return this;
else return this.slice(1).reverse() + this.slice(0,1);
}
Testlauf:
var s = "";
for(var i = 0; i < 1000; i++) {
s += ("apple" + i);
}
console.log(s.reverse());
Ausgabe:
999elppa899elppa...2elppa1elppa0elppa
Um zu versuchen , einen Stapelüberlauf immer, ich geändert , 1000
um 10000
in Google Chrome, und berichtete:
RangeError: Maximum call stack size exceeded
Zeichenfolgen selbst sind unveränderlich, aber Sie können problemlos eine umgekehrte Kopie mit dem folgenden Code erstellen:
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
Eine kleine Funktion, die sowohl diakritische Zeichen als auch 2-Byte-Zeichen kombiniert:
(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()
{
var output = "",
i = this.length - 1,
width;
for ( ; i >= 0; --i )
{
width = 1;
while( i > 0 && isCombiningDiacritic( this.charCodeAt(i) ) )
{
--i;
width++;
}
if (
i > 0
&& "\uDC00" <= this[i] && this[i] <= "\uDFFF"
&& "\uD800" <= this[i-1] && this[i-1] <= "\uDBFF"
)
{
--i;
width++;
}
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
].forEach(
function(str){ console.log( str + " -> " + str.reverse() ); }
);
Aktualisieren
Eine vollständigere Liste der Kombination von Diakritika lautet:
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);
};
isCombiningDiacritic
Funktion so zu bearbeiten , dass sie alle 316 Bereiche enthält. Fühlen Sie sich frei, diese Bearbeitung bereitzustellen, da Sie anscheinend die Daten zur Hand haben.
function reverseString(string) {
var reversedString = "";
var stringLength = string.length - 1;
for (var i = stringLength; i >= 0; i--) {
reversedString += string[i];
}
return reversedString;
}
ohne String in Array umzuwandeln;
String.prototype.reverse = function() {
var ret = "";
var size = 0;
for (var i = this.length - 1; -1 < i; i -= size) {
if (
'\uD800' <= this[i - 1] && this[i - 1] <= '\uDBFF' &&
'\uDC00' <= this[i] && this[i] <= '\uDFFF'
) {
size = 2;
ret += this[i - 1] + this[i];
} else {
size = 1;
ret += this[i];
}
}
return ret;
}
console.log('anãnam anañam' === 'mañana mañana'.reverse());
Verwenden von Array.reverse ohne Konvertieren von Zeichen in Codepunkte;
String.prototype.reverse = function() {
var array = this.split("").reverse();
for (var i = 0; i < this.length; ++i) {
if (
'\uD800' <= this[i - 1] && this[i - 1] <= '\uDBFF' &&
'\uDC00' <= this[i] && this[i] <= '\uDFFF'
) {
array[i - 1] = array[i - 1] + array[i];
array[i] = array[i - 1].substr(0, 1);
array[i - 1] = array[i - 1].substr(1, 1);
}
}
return array.join("");
}
console.log('anãnam anañam' === 'mañana mañana'.reverse());
var c = array[i-1]; array[i-1] = array[i]; array[i] = c;
erfordert keine Verkettung des Codepaars. Außerdem sollte die for-Schleife am 1.
'\ud83c\ud83c\udfa5'.reverse()
- sie gibt dieselbe Ausgabe aus wie die Eingabe. Das Hinzufügen ++i;
innerhalb der if
Anweisung sollte dies beheben.
'a\u0303bc'.reverse() === 'cba\u0303'
sollte true zurückgeben.
Ich denke, String.prototype.reverse ist ein guter Weg, um dieses Problem zu lösen. der Code wie folgt;
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";
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);
Mein eigener ursprünglicher Versuch ...
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"
Halten Sie es trocken und einfach albern!
function reverse(s){
let str = s;
var reverse = '';
for (var i=str.length;i>0;i--){
var newstr = str.substring(0,i)
reverse += newstr.substr(-1,1)
}
return reverse;
}
OK, ziemlich einfach, Sie können eine Funktion mit einer einfachen Schleife erstellen, um die Zeichenfolge für Sie umzukehren, ohne zu verwenden reverse()
.charAt()
etc wie folgt aus :
Zum Beispiel haben Sie diese Zeichenfolge:
var name = "StackOverflow";
Erstellen Sie eine Funktion wie diese, ich nenne es reverseString
...
function reverseString(str) {
if(!str.trim() || 'string' !== typeof str) {
return;
}
let l=str.length, s='';
while(l > 0) {
l--;
s+= str[l];
}
return s;
}
Und Sie können es so nennen:
reverseString(name);
Und das Ergebnis wird sein:
"wolfrevOkcatS"
Beste Möglichkeiten, eine Zeichenfolge in JavaScript umzukehren
1) Array.reverse:
Sie denken wahrscheinlich, warten Sie, ich dachte, wir kehren eine Zeichenfolge um. Warum verwenden Sie die Array.reverse-Methode? Mit der String.split-Methode konvertieren wir unseren String in ein Array von Zeichen. Dann kehren wir die Reihenfolge jedes Werts im Array um und konvertieren das Array schließlich mit der Methode Array.join zurück in einen String.
function reverseString(str) {
return str.split('').reverse().join('');
}
reverseString('dwayne');
2) Dekrementieren der while-Schleife:
Obwohl diese Lösung ziemlich ausführlich ist, hat sie ihre Vorteile gegenüber der ersten Lösung. Sie erstellen kein Array und verketten lediglich eine Zeichenfolge basierend auf Zeichen aus der Quellzeichenfolge.
Aus Sicht der Leistung würde dieser wahrscheinlich die besten Ergebnisse liefern (obwohl nicht getestet). Bei extrem langen Saiten können die Leistungssteigerungen jedoch aus dem Fenster fallen.
function reverseString(str) {
var temp = '';
var i = str.length;
while (i > 0) {
temp += str.substring(i - 1, i);
i--;
}
return temp;
}
reverseString('dwayne');
3) Rekursion
Ich finde es toll, wie einfach und klar diese Lösung ist. Sie können deutlich sehen, dass die Methoden String.charAt und String.substr verwendet werden, um einen anderen Wert zu durchlaufen, indem Sie sich jedes Mal selbst aufrufen, bis der String leer ist, von dem der Ternär nur einen leeren String zurückgibt, anstatt die Rekursion zu verwenden, um sich selbst aufzurufen . Dies würde wahrscheinlich die zweitbeste Leistung nach der zweiten Lösung ergeben.
function reverseString(str) {
return (str === '') ? '' : reverseString(str.substr(1)) + str.charAt(0);
}
reverseString('dwayne');