1

I have a function that accepts one input, an array, that can have X number of values. I have a string, which indicates the final format desired.

Example:

function doFormat(args) {
  const format = 'Foo \\d{1,2}x\\d{2} Bar';
}

doFormat([123, 2, 3]);

Let's assume, for now, that format will only contain a regex pattern that matches numbers with \\d, and that inputs will only contain numbers.

In this specific example, I want to coerce the input args into the string Foo 12x02 Bar, as required by the format variable, because the first match of \\d{1,2} restricts it to an integer with a maximum length of 2 (therefore trimming the first input, from 123 to just 12), and the second match of \\d{2} restricts to an integer with a length of exactly 2 (therefore padding the second input, from 2 to 02). And we drop the third input of 3, because it isn't used in format.

How can I achieve this? I'm using this in a Node script run on a server, so I can use any NPM packages, if necessary.

14
  • Your function does not use the argument (and it returns nothing). Commented Apr 19, 2018 at 20:47
  • Because I'm asking how to do it. The function doesn't do anything right now. I'm trying to get it to generate the output specified, given the args input and the format. I can remove the example if that would help... Commented Apr 19, 2018 at 20:48
  • This doesn't make sense. You have to be more specific of what you intend to accomplish. Commented Apr 19, 2018 at 20:53
  • Do you need your specific example (numbers with length) or can format be any valid regex? The latter sounds hard and my gut tells me it's also NP-complete Commented Apr 19, 2018 at 20:54
  • Let's assume that only numbers will be used as inputs. I'll try and figure out letters, later. Commented Apr 19, 2018 at 20:57

1 Answer 1

1

I've created npm package named to-fmt which uses literal templates to produce new string renderer function.

For your case it can work like so:

import f from 'to-fmt';

// Number formatter function
const num = (...args) => value => {
    let start;
    let end;

    const str = String(value);

    if (args.length > 1) {
        start = args[0];
        end = start + args[1];
    }
    else if (args.length) {
        start = 1;
        end = 1 + args[0];
    }
    else {
        start = 1;
        end = str.length;
    }

    const len = end - start;

    return str.slice(start - 1, end - 1)
    .padStart(len, '0')
    .slice(-len);
};

// Create new format:
const format = f`Foo ${num(1, 2)}x${num(2)} Bar`;

format(123, 2, 3); // -> 'Foo 12x02 Bar'
// And if you want to pass an Array
format(...[123, 2, 3]); // -> 'Foo 12x02 Bar'

Using template literal it is possible to create custom string formatters (and whatever you want). Provided package uses this to produce new function. It requires placeholders to be a functions which can convert values to strings.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.