Зацикливание Javascript на замене данных в строке

#javascript

#javascript

Вопрос:

У меня есть небольшой фрагмент кода, который я пытаюсь заменить. Есть два объекта данных. Один из них представляет собой список URL-адресов, содержащих {variable} , а другой — объект замещающих значений для этих переменных.

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

 // Content we will look through and replace variables in
let urls = [
    'http://www.example.com/{var1}/{var2}',
    'http://www.example.com/{var1}/{var4}',
];

// Data used for the replacement
let variables = [{
    variable: 'var1',
    value: '123'
},
{
    variable: 'var2',
    value: '456'
},
{
    variable: 'var4',
    value: '789'
}]

// Will hold the final URLs
let finalURLs = [];

// Loop over all URLS
for (let index = 0; index < urls.length;   index) {

    // Loop over all variables
    for (let d = 0; d < data.length;   d) {

        // Set the replaced URL
        let u = urls[index].replace('{'   data[d].variable   '}', data[d].value);
        finalURLs.push(u);

    }

}

// Desired output
finalURLs = [
    'http://www.example.com/123/456',
    'http://www.example.com/123/789'
]
  

Я уверен, что я далек от этого, но ищу некоторые указания о том, что делать.

Комментарии:

1. Что data я думаю, это должно быть variables

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

3. как это можно сделать? для 2 входных URL-адресов вы получите 6 выходных URL-адресов с этим кодом @Amunium

4. @JaromandaX — Да, и он случайно использовал data вместо variables . Есть несколько проблем, но вопрос был в эффективности, и там действительно нечего улучшать. Ему нужны два вложенных цикла, независимо от того, использует ли он вместо этого for-loops или map()/ forEach() . Концептуально в этом нет ничего плохого, ему просто нужно устранить ошибки.

Ответ №1:

Вы могли бы взять объект для замещающих строк и заменить все найденные значения.

 var urls = ['http://www.example.com/{var1}/{var2}', 'http://www.example.com/{var1}/{var4}'],
    vars = { var1: '123', var2: '456', var4: '789' },
    result = urls.map(s => s.replace(/{([^}]*?)}/g, (_, v) => v in vars ? vars[v] : v));

console.log(result);  

Комментарии:

1. Я не понимаю, какой второй аргумент в вашем методе замены? Функция с подчеркиванием в качестве параметра, который никогда не используется… что?

2. вам нужен заполнитель для параметра. _ является общим признаком того, что этот параметр не используется.

3. Согласно MDN, если функция передается в качестве параметра в методе replace, первым аргументом этой функции является сопоставленная строка, а вторым — сопоставленный n-й элемент, в этом случае подчеркивание соответствует строке {var} , а v — это то же самое, но без круглых скобок, можете ли вы мне это объяснить?

4. верно, но мне нужна только часть внутри завитушек, а не все совпадение.

Ответ №2:

Вы можете использовать Array.prototype.map(), Array.prototype.forEach() и String.prototype.replace(). Используйте регулярное выражение, чтобы применить замену глобально.

 const urls = [
  'http://www.example.com/{var1}/{var2}',
  'http://www.example.com/{var1}/{var4}',
];

const variables = [
  { variable: 'var1', value: '123' },
  { variable: 'var2', value: '456' },
  { variable: 'var4', value: '789' }
];

const result = urls.map(url => {
  variables.forEach(({ variable, value }) => {
    url = url.replace(new RegExp(`{${variable}}`, 'g'), value);
  });
  return url;
});

console.log(result);  

Комментарии:

1. лучший url.replace(регулярное выражение (переменная, g), значение);

Ответ №3:

Вы продолжаете заменять исходное значение urls[index] , а не значение, полученное в результате предыдущей замены.

 for (let index = 0; index < urls.length;   index) {
    let cur_url = urls[index];
    // Loop over all variables
    for (let d = 0; d < data.length;   d) {
        // Set the replaced URL
        cur_url = cur_url.replace('{'   data[d].variable   '}', data[d].value);   
    }
    finalURLs.push(cur_url);
}
  

Ответ №4:

Одним из вариантов было бы использовать регулярное выражение для сопоставления каждого, variable заключенного в квадратные скобки, а затем искать заменитель в объекте, индексируемом variable , значениями которого являются замены:

 // Content we will look through and replace variables in
let urls = [
    'http://www.example.com/{var1}/{var2}',
    'http://www.example.com/{var1}/{var4}',
];

// Data used for the replacement
let variables = [{
    variable: 'var1',
    value: '123'
},
{
    variable: 'var2',
    value: '456'
},
{
    variable: 'var4',
    value: '789'
}];
const replacements = variables.reduce((a, { variable, value }) => {
  a[variable] = value;
  return a;
}, {});

const pattern = new RegExp(
  Object.keys(replacements).map(needle => `{${needle}}`).join('|'),
  'g' // global match; replace all
);
const newUrls = urls.map(url => (
  url.replace(pattern, (needleWithBrackets) => {
    // Trim out the leading and trailing brackets:
    const needle = needleWithBrackets.slice(1, needleWithBrackets.length - 1);
    return replacements[needle];
  })
));
console.log(newUrls);  

Конечно, было бы лучше, если бы вы могли заранее объявить replacements :

 // Content we will look through and replace variables in
let urls = [
    'http://www.example.com/{var1}/{var2}',
    'http://www.example.com/{var1}/{var4}',
];
const replacements = {
  var1: 123,
  var2: 456,
  var4: 789
};

const pattern = new RegExp(
  Object.keys(replacements).map(needle => `{${needle}}`).join('|'),
  'g' // global match; replace all
);
const newUrls = urls.map(url => (
  url.replace(pattern, needleWithBrackets => replacements[needleWithBrackets.slice(1, needleWithBrackets.length - 1)])
));
console.log(newUrls);  

Ответ №5:

Похоже, что это можно решить с помощью строки шаблона.

 const variables = { var1: '123', var2: '323', var4:'254'}

const finalUrls = [
   `http://www.example.com/${variables.var1}/{variables.var2}`,
   `http://www.example.com/${variables.var1}/{variables.var4}`
]
  

Надеюсь, я понял ваш точный случай.

Еще одно замечание, если переменные могут содержать специальные символы, вам следует использовать encodeURI