I have this variable:
WelcomeText = 'Hi $0! Welcome to $1!';
And I am trying to create this function:
translate(WelcomeText, 'Daniel', 'Budapest');
Which should return this:
'Hi Daniel! Welcome to Budapest!'
I have tried to make this function which should support unlimited arguments to replace:
export const translator = (str, ...args) => {
let translate = args.map((item, index) => {
let stringToReplace = '$' + index;
let result = str.replace(stringToReplace, item);
return result;
});
console.log(translate);
};
But that gives me this:
["Hi Daniel! Welcome to $1", "Hi $0! Welcome to Budapest"]
Not sure how to explain it more than this, but I am out of words so I hope u can understand my problem with above :)
What am I doing wrong here, and what do I need to do to reach my desired result?
You can simply use forEach instead
let WelcomeText = 'Hi $0! Welcome to $1!'; const translator = (str, ...args) => { args.forEach((item, index) => { let stringToReplace = '$' + index; str= str.replace(stringToReplace, item); }); console.log(str); }; translator(WelcomeText, 'Daniel', 'Budapest');
Since you're using map in your original code so it returns a new string on every iteration and you endup getting an array of string, where in actual you need to get a string with all $
(index) instance replaced so you should be using the replaced string on next iteration onwards
You could take a function as replacement parameter and search for the index of the string.
const translate = (string, ...items) => string.replace(/\\$(\\d+)/g, (_, i) => items[i]), text = 'Hi $0! Welcome to $1!'; console.log(translate(text, 'Daniel', 'Budapest'));
map
always creates a new array of the same length, but you want to return a string. You could use reduce
instead with the text as the initial value:
var welcomeText = 'Hi $0! Welcome to $1!'; const translate = (t, ...args) => args.reduce((a, x, i) => a.replace(`$${i}`, x), t); console.log(translate(welcomeText, 'Daniel', 'Budapest'));
The problem is that Array#map
creates an array , so each replacement is treated as a separate thing to replace, so first you replace $0
and leave $1
but next time you're replacing from the original string and only replace $1
but leave $0
.
Since you don't need an array as a result, you can use Array#forEach
to just keep updating the str
every time:
const translator = (str, ...args) => { let translate = args.forEach((item, index) => { let stringToReplace = '$' + index; str = str.replace(stringToReplace, item); }); console.log(str); }; const WelcomeText = 'Hi $0! Welcome to $1!'; translator(WelcomeText, 'Daniel', 'Budapest');
Alternatively, you could use Array#reduce
and use the resulting value:
const translator = (str, ...args) => { let translate = args.reduce((result, item, index) => { let stringToReplace = '$' + index; return result.replace(stringToReplace, item); }, str); console.log(translate); }; const WelcomeText = 'Hi $0! Welcome to $1!'; translator(WelcomeText, 'Daniel', 'Budapest');
You can also String#replace
with a function as a replacer parameter, which will allow you to dynamically determine what the replacement would be:
const translator = (str, ...args) => { let translate = str.replace( /\\$(\\d+)/g, //match a pattern that has $ followed by a number, capture the number (match, placeholderNumber) => args[placeholderNumber] //replace with corresponding the value from args ) console.log(translate); }; const WelcomeText = 'Hi $0! Welcome to $1!'; translator(WelcomeText, 'Daniel', 'Budapest');
Try this
let name = args[0];
let place = args[1];
let message = 'Hi ${name}, welcome to ${place}`;
I would pass to translator array of arrays, like this:
const welcome = "Hi $0! Welcome to $1!";
const returnString = (str, name, city) =>
str.replace("$0", name).replace("$1", city);
const translator = (str, arr) => {
return arr.map(([name, city]) => returnString(str, name, city));
};
console.log(
translator(welcome, [
["John", "NY"],
["Sara", "LA"],
["Bill", "SF"]
])
);
output: ["Hi John! Welcome to NY!", "Hi Sara! Welcome to LA!", "Hi Bill! Welcome to SF!"]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.