0

Say I have a string like so:

const m = 'Map<?,?>';

and an array like so:

const types = ['string', 'boolean'];

and I am looking to generate:

const r = 'Map<string,boolean>'

how can I do that? Note that I don't need to use a question mark in the template string, I can use a different character, maybe like this:

const m = 'Map<%s,%s>';

Also please note that I cannot use ES6 template strings of this nature ${} because my template is not wrapped in a function.

I believe this will work in Node.js:

util.format(m, ...types);

but I guess what I am looking for is a way to use a question mark character (?) instead of using %s.

3 Answers 3

3

The smallest way is probably using a combination of reduce and replace.

Replace only replaces the first found position and reduce makes it easy to iterate over the given replacements.

const m = 'Map<?,?>';

const types = ['string', 'boolean'];

const n = types.reduce((n, t) => n.replace('?', t), m);
console.log(n);

Or to formalize it into a function:

function format(str, key, replacements){
    return replacements.reduce((s, t) => s.replace(k, t), str);
}
Sign up to request clarification or add additional context in comments.

14 Comments

probably a good idea to make a note on the comma operator, or explain that in the comments here. Oh just kidding, that's not a comma operator.
What do you mean by comma operator?
I misread your code, but this is the comma op: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
It's unclear to me whether you liked the OP or not? :)
This is probably the best answer possible. I'm just miffed that I never thought of iterating over a string like this, and especially in a way that works with a const string. Nice answer!
|
1

You can also use replace() directly with a little fancy closure work to capture the index (which sadly isn't passed to the replace callback function):

const m = 'Map<?,?>';
const types = ['string', 'boolean'];

let rep = m.replace(/\?/g, ((i) => () => types[i++])(0)) // i is simple a count of matches starting at 0
console.log(rep)

If the immediately-executed function is too weird, you can wrap the whole thing as a simple function that's a little easier on the eyes:

const m = 'Map<?,?>';
const types = ['string', 'boolean'];

function replaceMatch(str, arr){
    let i = 0
    return str.replace(/\?/g, () => arr[i++])
}

console.log(replaceMatch(m, types))

1 Comment

Interesting answer! That is one weird looking closure
0

You only need one ?

const types = ['string', 'boolean'];

console.log('Map<?>'.split('?').join(types))

or

const types = ['string', 'boolean'];

console.log('Map<?>'.replace('?', types))

or if you wished to keep ?,?

const types = ['string', 'boolean'];

console.log('Map<?,?>'.replace('?,?', types))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.