JavaScript - С точки зрения оптимизации, как заменить несколько подстрок в строке разными строками? - PullRequest
0 голосов
/ 11 марта 2020

В коде, который я разрабатываю и поддерживаю, я столкнулся с проблемой.

У меня есть функция, которая принимает запрос (строка типа) и заменяет подстроки этой строки другой строкой. Например, если пользователь вводит строку I have a cat, он заменяет ее на I have a dog.

Мой код работает, но проблема в том, что у меня есть сотни таких подстрок, которые необходимо заменить другой. , Это также выглядит очень плохо с эстетической точки зрения.

var myString;
myString = myString.replace('cat','dog')
                   .replace('elephant','zebra')
                   .replace('bird','fish')
                   // Goes on for hundreds of lines

Это все внутри функции, в которой каждый раз, когда она вызывается, она проходит через сотни replace вызовов.

Одна вещь, которую я мог бы попытаться сделать, это создание массива объектов и итерация по нему. Код будет выглядеть примерно так:

var animalsArray = [
                       {'a':'cat','b':'dog'},
                       {'a':'elephant','b':'zebra'},
                       {'a':'bird','b':'fish'}
                   ];

А потом в моей функции

function stringReplace(string) {
    for (var i = 0; i < animalsArray.length; i++) {
        if (string.indexOf(animalsArray[i]['a']) > -1) {
            sting = string.replace(animalsArray[i]['a'],animalsArray[i]['b']);
        }
    }
}

Но я не уверен, улучшит ли это мою нынешнюю практику объединения сотен заменить вызовы.

Я в основном ищу, чтобы оптимизировать мой текущий код. Какова лучшая практика?

Ответы [ 3 ]

1 голос
/ 11 марта 2020

Вы можете сделать регулярное выражение с кучей операторов или. (dog|elephant|bird|....), и это позволит вам выполнить одну проверку. Замена дает вам соответствующий текст, который вы можете использовать, чтобы найти слово для замены.

Итак, сделайте объект из строк для замены, а их значение - это слово для замены. Вы можете просто найти замену по соответствующему ключу.

const animals = {
  cat: 'dog',
  elephant: 'zebra',
  bird: 'fish',
}

// build the or sting with a simple join
const keysString = Object.keys(animals).join("|")
// generate the regular expression to match the words
var animalRE = new RegExp(`\\b(${keysString})\\b`,'g');

// a sample string to match
const myString = "I like to pet a cat that looks like an elephant that moves like a bird."

// the replacement step. The function takes the matched text (aka key) and looks it up in the object
const updated = myString.replace(animalRE, key => animals[key] || key)

// display the new string
console.log(updated)
0 голосов
/ 11 марта 2020

Я бы сделал что-то вроде:

function WordSwapper(sentence){
  const swapper = sentence;
  this.swaps = [];
  this.add = (word, replacer)=>{
    this.swaps.push([word, replacer]);
    return this;
  }
  this.swap = (sentence = null)=>{
    let s = sentence === null ? swapper : sentence;
    this.swaps.forEach(a=>{
      s = s.replace(new RegExp(a[0], 'gi'), a[1]);
    });
    return s;
  }
}
const ws = new WordSwapper('The cat plays. Elephants live in the Serengeti. Have you ever seen a bird fly?');
ws.add('cat', 'dog').add('elephant', 'zebra').add('bird', 'fish');
console.log(ws.swap());

Конечно, вы можете захотеть что-то сделать с множественными и заглавными буквами.

0 голосов
/ 11 марта 2020

Я бы подумал об использовании вместо этого объекта, ключи которого - это подстроки для замены, а значения - для замены. Сделайте регулярное выражение, чередуя все ключи объекта, затем используйте функцию заменителя, чтобы найти соответствующее значение на объекте:

const replacements = {
  cat: 'dog',
  elephant: 'zebra',
  bird: 'fish'
};
const pattern = new RegExp(Object.keys(replacements).join('|'), 'g');
console.log('Foo cat bar bird'.replace(pattern, match => replacements[match]));

Использование синтаксиса объектов позволяет легко добавлять / удалять элементы. Если вы хотите упростить изменение, вы можете вместо этого поместить информацию о замене в строку, а затем проанализировать ее в объекте:

const replacementsStr = `
cat        dog
elephant   zebra
bird       fish
`;

const replacements = Object.fromEntries(
  replacementsStr
    .trim()
    .split('\n')
    .map(line => line.split(/\s+/))
);
const pattern = new RegExp(Object.keys(replacements).join('|'), 'g');
console.log('Foo cat bar bird'.replace(pattern, match => replacements[match]));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...