2016-07-27 3 views
1

Я пытаюсь реализовать в своем коде эту строку замены функции:Заменить все с помощью IndexOf и пока петля в String.prototype

String.prototype.replaceAll = function(f,r) { 
    if (f != r) { 
    while (this.indexOf(f) !== -1) { 
     this = this.replace(f,r); 
    } 
    } else { 
    return this; 
    } 
}; 

И я уже пытался использовать это:

String.prototype.replaceAll = function(f,r) { 
    return this.split(f).join(r); 
}; 

Но эта последняя функция замены не работает с двумя или более символами в выражении поиска.

Так что мне действительно нужно использовать первую функцию с циклом while.

Кто-нибудь знает, в чем проблема первой проявленной функции?

+2

хорошо вы вроде обмана, используя 'String.prototype.replace' в реализации. Но вы знаете, что можете использовать 'string.replace (/ find/g, 'replacement')', если вы хотите заменить все, правильно? – naomik

+0

Танк вам за ответ! Я знаю, что я могу использовать/g и/gi. На самом деле, мой код уже работает с помощью replace/g. Но в какой-то момент я захотел использовать небольшую функцию, чтобы использовать RegExp. Но, как мы видели, без причины, цикл while не работал. – Yan

+0

Я предоставил гораздо более подробный ответ ниже – naomik

ответ

0
function(f,r) 
{ 
var str=this; 
if (f != r) { 
    while (str.indexOf(f) !== -1) { 
     str=str.replace(f,r); 
    } 
} 
return str.toString(); 
} 
1

Строки неизменны в JavaScript, поэтому такие вещи, как это не будет работать

// can't reassign `this` in String.prototype method ! 
this = this.replace(f,r) 

Вместо этого, вы должны вернуть новую строку из вашей функции

String.prototype.replaceAll = function replaceAll(f,r) { 
 
    if (this.indexOf(f) === -1) 
 
    return this.toString() 
 
    else 
 
    return this.replace(f, r).replaceAll(f,r) 
 
} 
 

 
console.log('foobar foobar'.replaceAll('foo', 'hello')) // => 'hellobar hellobar' 
 
console.log('foobar foobar'.replaceAll('o', 'x'))  // => 'fxxbar fxxbar'

Итак, это короткий ответ, если вы не возражаете, полагаясь на встроенные функции, такие как String.prototype.indexOf и String.prototype.replace


Если вы хотите реализовать их с нуля, вы можете сделать это с помощью очень простого JavaScript. Вам не нужно использовать цикл while. Вы можете, но заявление вроде & hellip;

Поэтому мне действительно нужно использовать первую функцию с циклом while.

& hellip; false.


Начнем с базовой функции find. Это работает как String.prototype.indexOf

function find(s, x) { 
    function loop(s, pos) { 
    if (s.substring(0, x.length) === x) 
     return pos 
    else if (s === '') 
     return -1 
    else 
     return loop(s.substring(1), pos + 1) 
    } 
    return loop(s, 0) 
} 

console.log(find('foobar', 'f')) // => 0 
console.log(find('foobar', 'bar')) // => 3 
console.log(find('foobar', 'x')) // => -1 
console.log(find('foobar', '')) // => 0 

Тогда А replace функция, которая работает, чтобы заменить один экземпляр x с y в строке s

function replace(s, x, y, idx) { 
    // idx is an optional parameter here for optimizing replaceAll 
    // you'll see it used in the next example 
    if (idx === undefined) 
    return replace(s, x, y, find(s, x)) 
    else if (idx === -1) 
    return s 
    else 
    return s.substring(0, idx) + y + s.substring(idx + x.length) 
} 

console.log(replace('foobar', 'foo', 'hello')) // => 'hellobar' 
console.log(replace('foobar', 'bar', 'hello')) // => 'foohello' 

Затем, внедрение replaceAll является простой рекурсивной функции

function replaceAll(s, x, y) { 
    var idx = find(s, x) 
    if (idx === -1) 
    return s 
    else 
    // use 4th parameter in replace function so index isn't recalculated 
    return replaceAll(replace(s, x, y, idx), x, y) 
} 

console.log(replaceAll('foobar foobar', 'foo', 'hello')) // => 'hellobar hellobar' 
console.log(replaceAll('foobar foobar', 'o', 'x') ) // => 'fxxbar fxxbar' 

Вы можете реализовать все эти функции на String.prototype, если хотите, так что бы работали такие вещи, как 'foobar'.replaceAll('o', 'x').

Если вам не нравится find, вы можете использовать инструкцию String.prototype.indexOf.С другой стороны, если вы делаете это как упражнение, и вы пытаетесь реализовать все это с нуля, вы даже можете зайти так далеко, чтобы не полагаться на String.prototype.substring, который я использовал здесь.


Кроме того, для чего это стоит, здесь ваш код работает отлично

String.prototype.replaceAll = function(f,r) { 
    return this.split(f).join(r); 
}; 

'foobar foobar'.replaceAll('foo', 'hello') 
// => "hellobar hellobar" 

'foobar foobar'.split('foo').join('hello') 
// => "hellobar hellobar" 
+0

Спасибо naomik! Я не обратил внимания на то, что «String» является ** Примитивным значением **, поэтому он является неизменным (в отличие от «Array» и «Object»). – Yan

Смежные вопросы