#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