Jezen Thomas
Jezen Thomas

Reputation: 13800

Chaining JS methods

I'm trying to insert some whitespace in a string if the string conforms to a certain format. Specifically, if the string consists of only numbers, and is exactly five characters in length, whitespace should be added between the third and fourth numbers.

Here's my test case:

function codeAddress() {
    var num_regex = /^\d+$/,
            input = $("#distributor-search").val(),
          address = (input.match(num_regex) && input.length == 5) ? input.split('').splice(3, 0 , ' ').join() : input ;

    console.log('The address is: ' + address);

    return false;
}

For some reason, chaining .split(), .splice() and .join() seems to not return anything. Where am I going wrong?

Upvotes: 4

Views: 1624

Answers (4)

Tim S.
Tim S.

Reputation: 13843

split() returns an array, splice() returns the array with the removed elements and join() returns the joined array like they should.

Looks like everything goes wrong at splice(). Instead of giving the remainders, you get the removed items.

My test:

var input = '123,789';
var output = input.split(',').splice(1, 0, '456').join(',');

console.log(output); // outputs nothing, because `splice(1, 0, '456')` doesn't remove any values

You could solve this by making a prototype that uses splice's functionality, like so:

Array.prototype.isplice = function() {
    var tmp = this;

    Array.prototype.splice.apply(tmp, Array.prototype.isplice.arguments);

    return tmp;
};

var output = input.split(',').isplice(1, 0, '456').join(',');
console.log(output); // outputs ["123", "456", "789"] as expected

Upvotes: 7

Luca
Luca

Reputation: 4273

You can't concatenate splice with join in your case:

splice(3, 0 , ' ').join()

remember that splice returns a new array containing the removed items, not the result array.

Upvotes: 1

Cerbrus
Cerbrus

Reputation: 72857

As others have explained, your function didn't work because .splice() returns the removed elements, instead of the resulting array.

Try using this regex, instead:

/^(\d\d\d)(\d\d)$/

It will only match a string if it's 5 digits long, it won't modify other strings.

Examples:

var s = '123456'.replace(/^(\d\d\d)(\d\d)$/, '$1 $2');
// "123456"
var s = '1234'.replace(/^(\d\d\d)(\d\d)$/, '$1 $2');
// "1234"
var s = '12345'.replace(/^(\d\d\d)(\d\d)$/, '$1 $2');
// "123 45"

So, in your case:

address = $("#distributor-search").val().replace(/^(\d\d\d)(\d\d)$/, '$1 $2');

Upvotes: 3

Pointy
Pointy

Reputation: 413712

Why not just use the regex itself?

var num_regex = /^(\d\d\d)(\d\d)$/,
        input = $("#distributor-search").val(),
      address = input.match(num_regex);
if (address) address = address[1] + ' ' + address[2];

That regex matches a five-digit string and groups the first three and last two digits together. If the test string matches, then the .match() function returns an array with the two groups in positions 1 and 2 (position 0 being the entire match).

Upvotes: 2

Related Questions