Як ви змінити рядок на місці (або в місці) в JavaScript , коли він передається функції із зворотним твердженням, без використання вбудованих функцій ( .reverse()
, і .charAt()
т.д.)?
Як ви змінити рядок на місці (або в місці) в JavaScript , коли він передається функції із зворотним твердженням, без використання вбудованих функцій ( .reverse()
, і .charAt()
т.д.)?
Відповіді:
Поки ви маєте справу з простими символами ASCII, і ви раді використовувати вбудовані функції, це буде працювати:
function reverse(s){
return s.split("").reverse().join("");
}
Якщо вам потрібно рішення, яке підтримує UTF-16 або інші багатобайтові символи, пам’ятайте, що ця функція надасть недійсні рядки Unicode або дійсні рядки, які виглядають смішно. Ви можете замість цього розглянути цю відповідь .
[... s] знає Unicode, невелика редакція дає:
function reverse(s){
return [...s].reverse().join("");
}
return [...s].reverse().join("");
може працювати.
Для обертання рядка в JavaScript зазвичай використовується наступна техніка (або схожа):
// Don’t use this!
var naiveReverse = function(string) {
return string.split('').reverse().join('');
}
Насправді, всі відповіді, розміщені до цього часу, є варіацією цієї закономірності. Однак з цим рішенням є деякі проблеми. Наприклад:
naiveReverse('foo 𝌆 bar');
// → 'rab �� oof'
// Where did the `𝌆` symbol go? Whoops!
Якщо вам цікаво, чому це відбувається, прочитайте про внутрішнє кодування символів JavaScript . (TL; DR: 𝌆
це астральний символ, а JavaScript розкриває його як дві окремі одиниці коду.)
Але є ще:
// 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.
Хорошим рядком для тестування зворотних реалізацій рядків є наступне :
'foo 𝌆 bar mañana mañana'
Чому? Оскільки він містить астральний символ ( 𝌆
) (який представлений сурогатними парами в JavaScript ) та об'єднувальний знак ( ñ
останнійmañana
насправді складається з двох символів: U + 006E LATIN SMALL LETTER N та U + 0303 COMBINING TILDE).
Порядок, в якому з’являються сурогатні пари, неможливо змінити, інакше астральний символ більше не відображатиметься в рядку «перевернутий». Ось чому ви побачили ці ��
позначки у висновку для попереднього прикладу.
Комбінуючі позначки завжди наносяться на попередній символ, тому ви повинні розглядати як основний символ (U + 006E LATIN SMALL LETTER N) як комбінуючий знак (U + 0303 COMBINING TILDE) в цілому. Повернення їх порядку призведе до того, що знак поєднання буде поєднаний з іншим символом у рядку. Ось чому приклад виведення мав ã
замість ñ
.
Сподіваємось, це пояснює, чому всі відповіді, розміщені до цих пір, неправильні .
Щоб відповісти на ваше первинне запитання - як [правильно] повернути рядок у JavaScript, - я написав невелику бібліотеку JavaScript, яка здатна змінити рядки, відомі Unicode. У ньому немає жодного з питань, про які я щойно згадував. Бібліотека називається Esrever ; його код знаходиться на GitHub, і він працює в майже будь-якому середовищі JavaScript. Він постачається з утилітою / бінарною оболонкою, тому ви можете легко повернути рядки зі свого терміналу, якщо хочете.
var input = 'foo 𝌆 bar mañana mañana';
esrever.reverse(input);
// → 'anañam anañam rab 𝌆 oof'
Щодо частини "на місці", дивіться інші відповіді.
String.prototype.reverse_string=function() {return this.split("").reverse().join("");}
або
String.prototype.reverse_string = function() {
var s = "";
var i = this.length;
while (i>0) {
s += this.substring(i-1,i);
i--;
}
return s;
}
Детальний аналіз та десять різних способів повернути рядок та деталі їх продуктивності.
http://eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript/
Виконання цих реалізацій:
Найефективніші впровадження для кожного браузера
Ось такі реалізації:
Впровадження 1:
function reverse(s) {
var o = '';
for (var i = s.length - 1; i >= 0; i--)
o += s[i];
return o;
}
Впровадження 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('');
}
Виконання 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('');
}
Впровадження 4:
function reverse(s) {
return s.split('').reverse().join('');
}
Впровадження 5:
function reverse(s) {
var i = s.length,
o = '';
while (i > 0) {
o += s.substring(i - 1, i);
i--;
}
return o;
}
Реалізація 6:
function reverse(s) {
for (var i = s.length - 1, o = ''; i >= 0; o += s[i--]) { }
return o;
}
Впровадження 7:
function reverse(s) {
return (s === '') ? '' : reverse(s.substr(1)) + s.charAt(0);
}
Реалізація 8:
function reverse(s) {
function rev(s, len, o) {
return (len === 0) ? o : rev(s, --len, (o += s[len]));
};
return rev(s, s.length, '');
}
Впровадження 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('');
}
Впровадження 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));
}
Весь "зворотний рядок на місці" - це стародавнє питання інтерв'ю програмістів C, і люди, які опитали їх (для помсти, можливо?), Запитають. На жаль, це частина "In Place" вже не працює, оскільки рядки в майже будь-якій керованій мові (JS, C # тощо) використовують незмінні рядки, тим самим перемагаючи всю ідею переміщення рядка, не виділяючи жодної нової пам'яті.
Хоча рішення, наведені вище, дійсно зворотно змінюють рядок, вони не роблять це, не виділяючи більше пам'яті, і, таким чином, не відповідають умовам. Потрібно мати прямий доступ до виділеного рядка та мати можливість маніпулювати його вихідним місцем пам'яті, щоб мати змогу повернути його на місце.
Особисто я дуже ненавиджу подібні питання інтерв'ю, але, на жаль, я впевнений, що ми продовжуємо їх бачити на довгі роки.
Спочатку використовуйте, Array.from()
щоб перетворити рядок у масив, потім Array.prototype.reverse()
повернути масив, а потім Array.prototype.join()
повернути його рядок.
const reverse = str => Array.from(str).reverse().join('');
reverse
логіки.
string.split('')
не працює. Дивіться цю відповідь для отримання додаткових пояснень.
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('')
стане"anañam anañam rab 𝌆 oof"
У ECMAScript 6 ви можете змінити рядок ще швидше, не використовуючи .split('')
метод розділення, за допомогою оператора розповсюдження так:
var str = [...'racecar'].reverse().join('');
string.split('')
більш зрозуміло для більшості людей, ніж [...string]
.
.split('')
має проблему з символами з додаткових площин (сурогатних пар в UTF-16), оскільки він розбивається на кодову одиницю UTF-16, а не на кодову точку . Оператор розповсюдження та Array.from()
(на мою перевагу) цього не роблять.
Здається, я запізнився на 3 роки на вечірку ...
На жаль, ви не можете, як було зазначено. Див. Чи не змінюються рядки JavaScript? Чи потрібен "конструктор струн" у JavaScript?
Наступне найкраще, що ви можете зробити - це створити "view" або "обгортку", яка займає рядок і повторно реалізує всі частини API рядка, якими ви користуєтесь, але прикидаючи, що рядок є зворотним. Наприклад:
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
Демонстрація:
> 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"
Кікер - наступне робиться на місці чистою математикою, відвідуючи кожного персонажа лише один раз, і лише за потреби:
> 'demo: ' + S('0123456789abcdef').slice(3).reversed().slice(1,-1).toUpperCase()
"demo: EDCBA987654"
> S('0123456789ABCDEF').slice(3).reversed().slice(1,-1).toLowerCase().charAt(3)
"b"
Це дає значну економію, якщо застосовувати її до дуже великої струни, якщо ви берете лише порівняно невеликий шматочок.
Чи варто цього вартий (над реверсіруемой копією, як у більшості мов програмування) сильно залежить від вашого випадку використання та того, наскільки ефективно ви повторно реалізуєте API рядка. Наприклад, якщо все, що вам потрібно, це зробити маніпуляцію з індексами рядків або взяти невеликі slice
s або substr
s, це заощадить ваш простір та час. Якщо ви плануєте друкувати великі перевернуті фрагменти або підрядки, то економія може бути дійсно невеликою, навіть гіршою, ніж зробити повну копію. Ваш "обернений" рядок також не буде мати тип string
, хоча ви, можливо, зможете підробити це під час прототипування.
Вищеописана демонстраційна реалізація створює новий об'єкт типу ReversedString. Він є прототипом і, отже, досить ефективним, з майже мінімальною роботою та мінімальними витратами на простір (визначення прототипу є спільними). Це ледача реалізація, що передбачає відкладені нарізки. Кожен раз, коли ви виконуєте функцію на кшталт .slice
або .reversed
, вона виконуватиме математику індексу. Нарешті, коли ви виймаєте дані (неявно зателефонувавши .toString()
або .charCodeAt(...)
щось таке), вони застосовуватимуться "розумним" способом, торкаючись найменш можливих даних.
Примітка. Наведений вище рядок API є прикладом, і він не може бути реалізований ідеально. Ви також можете використовувати лише 1-2 функції, які вам потрібні.
Існує багато способів змінити рядок у JavaScript. Я записую три способи, які я віддаю перевагу.
Підхід 1: Використання функції зворотного зв'язку:
function reverse(str) {
return str.split('').reverse().join('');
}
Підхід 2: перегляд символів:
function reverse(str) {
let reversed = '';
for (let character of str) {
reversed = character + reversed;
}
return reversed;
}
Підхід 3: Використання функції зменшення:
function reverse(str) {
return str.split('').reduce((rev, char) => char + rev, '');
}
Сподіваюся, це допомагає :)
Під час інтерв'ю мене попросили повернути рядок, не використовуючи змінних або нативних методів. Це моя улюблена реалізація:
function reverseString(str) {
return str === '' ? '' : reverseString(str.slice(1)) + str[0];
}
slice
? : - /
Array.prototype.reverse()
.
Існує кілька способів зробити це, ви можете перевірити наступне,
1. Традиційні для циклу (збільшення):
function reverseString(str){
let stringRev ="";
for(let i= 0; i<str.length; i++){
stringRev = str[i]+stringRev;
}
return stringRev;
}
alert(reverseString("Hello World!"));
2. Традиційні для циклу (декрементація):
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. Використання циклу for-of
function reverseString(str){
let strn ="";
for(let char of str){
strn = char + strn;
}
return strn;
}
alert(reverseString("Get well soon"));
4. Використовуючи метод масиву forEach / high order:
function reverseString(str){
let revSrring = "";
str.split("").forEach(function(char){
revSrring = char + revSrring;
});
return revSrring;
}
alert(reverseString("Learning JavaScript"));
5. Стандарт ES6:
function reverseString(str){
let revSrring = "";
str.split("").forEach(char => revSrring = char + revSrring);
return revSrring;
}
alert(reverseString("Learning JavaScript"));
6. Останній спосіб:
function reverseString(str){
return str.split("").reduce(function(revString, char){
return char + revString;
}, "");
}
alert(reverseString("Learning JavaScript"));
7. Ви також можете отримати результат, використовуючи наступне,
function reverseString(str){
return str.split("").reduce((revString, char)=> char + revString, "");
}
alert(reverseString("Learning JavaScript"));
У ES6 у вас є ще один варіант
function reverseString (str) {
return [...str].reverse().join('')
}
reverseString('Hello');
Це найпростіший спосіб, на який я думаю
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()
це було б найпростішим способом, отже, найпопулярнішою відповіддю. Звичайно, це потребує хороших попередніх знань JavaScript.
Я знаю, що це старе питання, на яке добре відповіли, але для власного розваги я написав таку зворотню функцію і подумав, що поділюсь нею, якщо це буде корисним для когось іншого. Він обробляє як сурогатні пари, так і комбінуючі позначки:
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('');
}
Усі реквізити до Mathias, Punycode та різні інші посилання на навчання мені про складність кодування символів у JavaScript.
Ви не можете, оскільки рядки JS незмінні. Коротке немісцеве рішення
[...str].reverse().join``
Якщо ви не хочете використовувати будь-яку вбудовану функцію. Спробуйте це
var string = 'abcdefg';
var newstring = '';
for(let i = 0; i < string.length; i++){
newstring = string[i] += newstring;
}
console.log(newstring);
Справжня відповідь: ви не можете змінити її на місці, але ви можете створити новий рядок, який є зворотним.
Як вправа грати з рекурсією: іноді, коли ви йдете на співбесіду, інтерв'юер може запитати вас, як це зробити за допомогою рекурсії, і я думаю, що "бажана відповідь" може бути ", я б краще не робив цього в рекурсії, як це може легко спричинити переповнення стека "(тому, що це O(n)
швидше, ніж O(log n)
. Якщо це так O(log n)
, досить складно отримати переповнення стека - 4 мільярди елементів можна було б обробити рівнем стека 32, оскільки 2 ** 32 становить 4294967296. Але якщо це так O(n)
, то він може легко отримати переповнення стека.
Іноді інтерв'ю все ще запитає у вас, "як вправу, чому б ви все-таки не написали це за допомогою рекурсії?" І ось це:
String.prototype.reverse = function() {
if (this.length <= 1) return this;
else return this.slice(1).reverse() + this.slice(0,1);
}
пробіг:
var s = "";
for(var i = 0; i < 1000; i++) {
s += ("apple" + i);
}
console.log(s.reverse());
вихід:
999elppa899elppa...2elppa1elppa0elppa
Щоб спробувати отримати переповнення стека, я змінив 1000
на 10000
Google Chrome, і він повідомив:
RangeError: Maximum call stack size exceeded
//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
Невелика функція, яка поєднує діакритику та двобайтові символи:
(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() ); }
);
Оновлення
Більш повний перелік об'єднаних діакритиків:
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
функції, що включає всі 316 діапазони; не соромтеся надати це редагування, оскільки, здається, у вас є дані.
function reverseString(string) {
var reversedString = "";
var stringLength = string.length - 1;
for (var i = stringLength; i >= 0; i--) {
reversedString += string[i];
}
return reversedString;
}
без перетворення рядка в масив;
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());
використання Array.reverse без перетворення символів у кодові точки;
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;
не потрібно об'єднання пари коду. Також цикл for-loop повинен починатися з 1.
'\ud83c\ud83c\udfa5'.reverse()
- вона виведе так само, як і вхід. Додавання ++i;
в if
оператор має це виправити.
'a\u0303bc'.reverse() === 'cba\u0303'
слід повернути істину.
Я думаю, що String.prototype.reverse - це хороший спосіб вирішити цю проблему; код, як показано нижче;
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);
Моя власна оригінальна спроба ...
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"
Тримайте це ДУХО і просто нерозумно !!
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;
}
Добре, досить просто, ви можете створити функцію з допомогою простого циклу , щоб гарантувати рядку зворотної для вас без використання reverse()
, і charAt()
т.д. , як це:
Наприклад, у вас є ця рядок:
var name = "StackOverflow";
Створіть таку функцію, як я її називаю 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;
}
І ви можете назвати це так:
reverseString(name);
І результат буде:
"wolfrevOkcatS"
Найкращі способи повернути рядок у JavaScript
1) Array.reverse:
Ви, напевно, думаєте, чекайте, я думав, що ми повернули рядок, чому ви використовуєте метод Array.reverse. Використовуючи метод String.split, ми перетворюємо наш рядок у масив символів. Потім ми реверсуємо порядок кожного значення в масиві, а потім, нарешті, перетворюємо масив назад у рядок за допомогою методу Array.join.
function reverseString(str) {
return str.split('').reverse().join('');
}
reverseString('dwayne');
2) Зменшення в циклі:
Хоча це досить багатослівне, це рішення має свої переваги перед рішенням. Ви не створюєте масив, а ви просто об'єднуєте рядок на основі символів з вихідного рядка.
З точки зору ефективності, це, мабуть, дасть найкращі результати (хоча і не перевірено). Для надзвичайно довгих рядків, однак підвищення продуктивності може випасти з вікна.
function reverseString(str) {
var temp = '';
var i = str.length;
while (i > 0) {
temp += str.substring(i - 1, i);
i--;
}
return temp;
}
reverseString('dwayne');
3) Рекурсія
Мені подобається, наскільки просто і зрозуміло це рішення. Ви чітко бачите, що методи String.charAt і String.substr використовуються для проходження різного значення, викликаючи себе щоразу, поки рядок не буде порожнім, з якого потрійний просто поверне порожню рядок замість того, щоб використовувати рекурсію для виклику себе . Це, ймовірно, призведе до другого найкращого результату після другого рішення.
function reverseString(str) {
return (str === '') ? '' : reverseString(str.substr(1)) + str.charAt(0);
}
reverseString('dwayne');