如何在JavaScript中反转字符串?

问题描述 投票:392回答:44

当传递给带有return语句的函数时,如何在JavaScript中就地(或就地)转换字符串?所有没有使用内置函数(.reverse().charAt()等)?

javascript string reverse
44个回答
695
投票

只要您处理简单的ASCII字符,并且您很乐意使用内置函数,这将有效:

function reverse(s){
    return s.split("").reverse().join("");
}

如果您需要支持UTF-16或其他多字节字符的解决方案,请注意此函数将提供无效的unicode字符串或看起来很有趣的有效字符串。你可能想要考虑this answer instead


9
投票

有很多方法可以在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:使用reduce函数:

function reverse(str) {
  return str.split('').reduce((rev, char) => char + rev, '');
}

我希望这有帮助 :)


8
投票

有多种方法,你可以检查以下,

1.传统的for循环(递增):

function reverseString(str){
        let stringRev ="";
        for(let i= 0; i<str.length; i++){
            stringRev = str[i]+stringRev;
        }
        return stringRev;
}
alert(reverseString("Hello World!"));

2.传统的for循环(递减):

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"));

6
投票

这是我认为最简单的方法

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 🍺'));

6
投票
var str = 'sample string';
[].map.call(str, function(x) {
  return x;
}).reverse().join('');

要么

var str = 'sample string';
console.log(str.split('').reverse().join(''));

//输出:'gnirts elpmas'


5
投票

我知道这是一个老问题已经得到很好的回答,但为了我自己的乐趣,我编写了以下反向功能,并认为我会分享它,以防它对其他人有用。它处理代理对和组合标记:

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中字符编码的复杂性。


5
投票

在ES6中,您还有一个选项

function reverseString (str) {
  return [...str].reverse().join('')
}

reverseString('Hello');

2
投票

真正的答案是:你不能在适当的位置反转它,但你可以创建一个相反的新字符串。

就像练习递归一样:有时当你去面试时,面试官可能会问你如何使用递归来做到这一点,我认为“首选答案”可能是“我宁愿不在递归中这样做,因为它很容易导致堆栈溢出“(因为它是O(n)而不是O(log n)。如果它是O(log n),很难获得堆栈溢出 - 40亿个项目可以通过堆栈级别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

为了尝试获得堆栈溢出,我在Google Chrome中将1000更改为10000,并报告:

RangeError: Maximum call stack size exceeded

2
投票

字符串本身是不可变的,但您可以使用以下代码轻松创建反向副本:

function reverseString(str) {

  var strArray = str.split("");
  strArray.reverse();

  var strReverse = strArray.join("");

  return strReverse;
}

reverseString("hello");

2
投票

一个小函数,可以处理变音符号和2字节字符的组合:

(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() ); }
);
  

2
投票
//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

396
投票

以下技术(或类似)通常用于在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!

如果你想知道为什么会这样,read up on JavaScript’s internal character encoding。 (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.

测试字符串反向实现的一个好字符串是the following

'foo 𝌆 bar mañana mañana'

为什么?因为它包含一个星体符号(𝌆)(它是represented by surrogate pairs in JavaScript)和一个组合标记(最后一个中的mañana实际上由两个符号组成:U + 006E LATIN SMALL LETTER N和U + 0303 COMBINING TILDE)。

代理对出现的顺序不能反转,否则星形符号将不再出现在“反向”字符串中。这就是为什么你在上一个例子的输出中看到那些��标记的原因。

组合标记始终应用于上一个符号,因此您必须将主符号(U + 006E LATIN SMALL LETTER N)作为组合标记(U + 0303 COMBINING TILDE)整体处理。反转它们的顺序将使组合标记与字符串中的另一个符号配对。这就是为什么示例输出有而不是ñ

希望这能解释为什么到目前为止发布的所有答案都是错误的。


为了回答你的初始问题 - 如何[正确]反转JavaScript中的字符串 - ,我编写了一个能够识别Unicode的字符串反转的小型JavaScript库。它没有我刚才提到的任何问题。该图书馆名为Esrever;它的代码在GitHub上,几乎适用于任何JavaScript环境。它带有一个shell实用程序/二进制文件,因此如果需要,您可以轻松地从终端中反转字符串。

var input = 'foo 𝌆 bar mañana mañana';
esrever.reverse(input);
// → 'anañam anañam rab 𝌆 oof'

至于“就地”部分,请参阅其他答案。


2
投票

如果您不想使用任何内置函数。试试这个

        var string = 'abcdefg';
        var newstring = '';

        for(let i = 0; i < string.length; i++){
            newstring = string[i] += newstring
        }

        console.log(newstring)

1
投票
function reverseString(string) {
    var reversedString = "";
    var stringLength = string.length - 1;
    for (var i = stringLength; i >= 0; i--) {
        reversedString += string[i];
    }
    return reversedString;
}

1
投票

没有将字符串转换为数组;

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());

1
投票

我认为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";

1
投票

使用数组函数,

String.prototype.reverse = function(){
    return [].reduceRight.call(this, function(last, secLast){return last + secLast});
}

1
投票
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);

1
投票

我原来的尝试......

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


1
投票

保持干爽简单傻!

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;
}

1
投票

好的,非常简单,您可以创建一个带有简单循环的函数来为您执行字符串反向,而不使用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"

1
投票

在JavaScript中反转字符串的最佳方法

1)Array.reverse:

你可能在想,等我认为我们正在反转一个字符串,你为什么要使用Array.reverse方法。使用String.split方法,我们将字符串转换为字符数组。然后我们颠倒数组中每个值的顺序,最后我们使用Array.join方法将Array转换回String。

function reverseString(str) {
    return str.split('').reverse().join('');
}
reverseString('dwayne');

2)减少while循环:

虽然非常冗长,但这个解决方案确实比解决方案更具优势。您没有创建数组,而只是根据源字符串中的字符连接字符串。

从性能的角度来看,这个可能会产生最好的结果(虽然未经测试)。对于极长的字符串,性能增益可能会从窗口中消失。

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');

88
投票
String.prototype.reverse=function(){return this.split("").reverse().join("");}

要么

String.prototype.reverse = function() {
    var s = "";
    var i = this.length;
    while (i>0) {
        s += this.substring(i-1,i);
        i--;
    }
    return s;
}

1
投票

以下是可用于实现字符串反转的四种最常用方法

给定一个字符串,返回一个反转字符顺序的新字符串

该问题的多种解决方案

//reverse('apple') === 'leppa'
//reverse('hello') === 'olleh'
//reverse('Greetings!') === '!sgniteerG'

// 1. First method without using reverse function and negative for loop
function reverseFirst(str) {
    if(str !== '' || str !==undefined || str !== null) {
        const reversedStr = [];
        for(var i=str.length; i>-1; i--) {
        reversedStr.push(str[i]);
        }
    return reversedStr.join("").toString();
    }
}

// 2. Second method using the reverse function
function reverseSecond(str) {
    return str.split('').reverse().join('');
}

// 3. Third method using the positive for loop
function reverseThird(str){
    const reversedStr = [];
    for(i=0; i<str.length;i++) {
        reversedStr.push(str[str.length-1-i])
    }
    return reversedStr.join('').toString();
}

// 4. using the modified for loop ES6
function reverseForth(str) {
    const reversedStr = [];
    for(let character of str) {
        reversedStr = character + reversedStr;
    }
    return reversedStr;
}

// 5. Using Reduce function
function reverse(str) {
    return str.split('').reduce((reversed, character) => {
        return character + reversed;  
    }, '');
}

53
投票

详细分析和十种不同的方法来反转字符串及其性能细节。

http://eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript/

这些实现的性能:

每个浏览器的最佳性能实现

  • Chrome 15 - 实施1和6
  • Firefox 7 - 实施6
  • IE 9 - 实施4
  • Opera 12 - 实施9

以下是这些实现:

实施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));
}

51
投票

整个“反向串起来”是一个过时的面试问题C程序员,他们接受采访的人(为了复仇,也许?)会问。不幸的是,它是“In Place”部分不再有效,因为几乎所有托管语言(JS,C#等)中的字符串都使用不可变字符串,从而无法在不分配任何新内存的情况下移动字符串。

虽然上面的解决方案确实会反转字符串,但如果不分配更多内存,它们就不会这样做,因此不满足条件。您需要直接访问已分配的字符串,并能够操纵其原始内存位置以便能够将其反转到位。

就个人而言,我真的很讨厌这些面试问题,但遗憾的是,我相信我们会在未来几年继续看到它们。


37
投票

首先,使用Array.from()将字符串转换为数组,然后使用Array.prototype.reverse()来反转数组,然后使用Array.prototype.join()将其转换为字符串。

const reverse = str => Array.from(str).reverse().join('');

24
投票

在ECMAScript 6中,你可以更快地反转字符串而不使用.split('') split方法,spread operator就像这样:

var str = [...'racecar'].reverse().join('');

19
投票

好像我迟到了3年...

不幸的是你不能像我们指出的那样。见Are JavaScript strings immutable? Do I need a "string builder" in JavaScript?

您可以做的另一件好事是创建一个“视图”或“包装器”,它接受一个字符串并重新实现您正在使用的字符串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的效率。例如,如果您只想进行字符串索引操作,或者使用小的slices或substrs,这将节省您的空间和时间。但是,如果您计划打印大型反转切片或子串,那么节省的确可能很小,甚至比完整副本更糟糕。你的“反向”字符串也不会有string类型,尽管你可以通过原型设计伪造它。

上面的演示实现创建了一个ReversedString类型的新对象。它是原型的,因此效率很高,几乎只需要很少的工作量和最小的空间开销(共享原型定义)。这是一个涉及延迟切片的惰性实现。每当你执行像.slice.reversed这样的函数时,它将执行索引数学。最后,当您提取数据时(通过隐式调用.toString().charCodeAt(...)或其他内容),它将以“智能”方式应用这些数据,触及可能的最少数据。

注意:上面的字符串API是一个示例,可能无法完美实现。您还可以使用您需要的1-2个功能。


10
投票

在一次采访中,我被要求在不使用任何变量或本机方法的情况下反转字符串。这是我最喜欢的实现:

function reverseString(str) {
    return str === '' ? '' : reverseString(str.slice(1)) + str[0];
}
© www.soinside.com 2019 - 2024. All rights reserved.