Regex problem

D

Doris

A list of points, defined by x and y coordinates, is to reversed. The list
may be three to five points long. So for example

list3 = '1,2,3,4,5,6'; // should give '5,6,3,4,1,2'
list4 = '1,2,3,4,5,6,7,8'; // will get '7,8,5,6,3,4,1,2'

I am looking for a regular expression which will capture all these possible
lengths in one pattern, but am having trouble removing and adding back in
the commas. I can do it with three calls to the replace method, but there
must be a better, more flexible and elegant solution:

newlist = listx.replace( /^(\d+,\d+),(\d+,\d+),(\d+,\d+)$/,
'$3,$2,$1' ).replace( /^(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+)$/,
'$4,$3,$2,$1' ).replace(
/^(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+)$/, '$5,$4,$3,$2,$1' );

Any hints?

Thanks,
Doris
 
S

Stevo

Doris said:
A list of points, defined by x and y coordinates, is to reversed. The list
may be three to five points long. So for example

list3 = '1,2,3,4,5,6'; // should give '5,6,3,4,1,2'
list4 = '1,2,3,4,5,6,7,8'; // will get '7,8,5,6,3,4,1,2'

I am looking for a regular expression which will capture all these possible
lengths in one pattern, but am having trouble removing and adding back in
the commas. I can do it with three calls to the replace method, but there
must be a better, more flexible and elegant solution:

newlist = listx.replace( /^(\d+,\d+),(\d+,\d+),(\d+,\d+)$/,
'$3,$2,$1' ).replace( /^(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+)$/,
'$4,$3,$2,$1' ).replace(
/^(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+)$/, '$5,$4,$3,$2,$1' );

Any hints?

Thanks,
Doris

Much easier with code if you ask me.

function reverseCoords(s)
{
var ar=s.split(",");
var ret="";
for(var i=ar.length-2;i>=0;i-=2)
{
ret+=ar+","+ar[i+1];
ret+=i>0?",":"";
}
return ret;
}
 
E

Evertjan.

Stevo wrote on 22 feb 2010 in comp.lang.javascript:
Doris said:
A list of points, defined by x and y coordinates, is to reversed. The
list may be three to five points long. So for example

list3 = '1,2,3,4,5,6'; // should give '5,6,3,4,1,2'
list4 = '1,2,3,4,5,6,7,8'; // will get '7,8,5,6,3,4,1,2'

I am looking for a regular expression which will capture all these
possible lengths in one pattern, but am having trouble removing and
adding back in the commas. I can do it with three calls to the
replace method, but there must be a better, more flexible and elegant
solution:

newlist = listx.replace( /^(\d+,\d+),(\d+,\d+),(\d+,\d+)$/,
'$3,$2,$1' ).replace( /^(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+)$/,
'$4,$3,$2,$1' ).replace(
/^(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+)$/,
'$5,$4,$3,$2,$1' );

Any hints?

Thanks,
Doris

Much easier with code if you ask me.

function reverseCoords(s)
{
var ar=s.split(",");
var ret="";
for(var i=ar.length-2;i>=0;i-=2)
{
ret+=ar+","+ar[i+1];
ret+=i>0?",":"";
}
return ret;
}


Without any code loping or local variable, any length:

function reverseCoords(s) {
return s.replace(/(\d+),(\d+)/g,'$1x$2').split(",").
reverse().join(',').replace(/x/g,',');
};
 
T

Thomas 'PointedEars' Lahn

Doris said:
A list of points, defined by x and y coordinates, is to reversed. The
list may be three to five points long. So for example

list3 = '1,2,3,4,5,6'; // should give '5,6,3,4,1,2'
list4 = '1,2,3,4,5,6,7,8'; // will get '7,8,5,6,3,4,1,2'

I am looking for a regular expression which will capture all these
possible lengths in one pattern, but am having trouble removing and
adding back in the commas. I can do it with three calls to the replace
method, but there must be a better, more flexible and elegant solution:

newlist = listx.replace( /^(\d+,\d+),(\d+,\d+),(\d+,\d+)$/,
'$3,$2,$1' ).replace( /^(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+)$/,
'$4,$3,$2,$1' ).replace(
/^(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+),(\d+,\d+)$/, '$5,$4,$3,$2,$1' );

Any hints?

A)

var m,
rxCoord = /\d+,\d+/g,
newlist = [];

while ((m = rxCoord.exec(listx)))
{
newlist.unshift(m[0]);
}

/*
* Can be omitted if you use `newlist' only in place of a string,
* as newlist.toString() === newlist.join() === newlist.join(",").
*/
newlist = newlist.join();

B)

var
items = listx.split(","),
newlist = [];

for (var i = items.length; (i -= 2) > -1;)
{
/* works here because slice() returns an Array reference */
newlist.push(items.slice(i, i+2));
}

/* see above */
newlist = newlist.join();

C)

var
items = listx.split(","),
newlist = [];

while (items.length)
{
var y = items.pop();
var x = items.pop();
newlist.push(x, y);
}

/* see above */
newlist = newlist.join();

I would not be storing the coordinates in a string value to begin with,
instead in an Array of the form [[x1, y1], [x2, y2], ...], but you might
not have that choice.


HTH

PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:
Doris said:
A list of points, defined by x and y coordinates, is to reversed. The
list may be three to five points long. So for example

list3 = '1,2,3,4,5,6'; // should give '5,6,3,4,1,2'
list4 = '1,2,3,4,5,6,7,8'; // will get '7,8,5,6,3,4,1,2'
[...]
Any hints?

[A) to C)]

D)

var newlist = listx.match(/\d+,\d+/g).reverse().join();

:)


PointedEars
 
D

Doris

"Thomas 'PointedEars' Lahn" said...
var newlist = listx.match(/\d+,\d+/g).reverse().join();

:)

PointedEars

Naturally..
A quick follow up question (that I really should not be bothering you with
before trying myself, but I have little to no idea where to begin atm): what
would be the simplest method of determining the direction of travel along
those points, ie. clockwise or counterclockwise, or figure-of-eight-wise if
there are more than three?.
Thank you all very much. It has been a fruitful endeavour so far.
Doris
 
T

Thomas 'PointedEars' Lahn

Doris said:
A quick follow up question (that I really should not be bothering you
with before trying myself, but I have little to no idea where to begin
atm):
what would be the simplest method of determining the direction of travel
along those points, ie. clockwise or counterclockwise, or
figure-of-eight-wise if there are more than three?.

Sorry, I really won't do *all* of your homework. It is there for
you to repeat and apply what you should have learned in class.
Thank you all very much. It has been a fruitful endeavour so far.

You are welcome. Please fix your From header, though.


PointedEars
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected].

To your first question : RegExp /.*/ will capture all of those, so use
newlist = oldlist.replace(/.*/, F)
A quick follow up question (that I really should not be bothering you with
before trying myself, but I have little to no idea where to begin atm): what
would be the simplest method of determining the direction of travel along
those points, ie. clockwise or counterclockwise, or figure-of-eight-wise if
there are more than three?.

Remember that they could be collinear. You could be talking about as
seen from the origin, but I expect you mean just referring to the line
itself.

Call the points 1 2 3. Math.atan2(y2-y1, x2-x1) gives the direction of
the first segment, similarly for the second. Find the difference,
adjust it by a multiple of 2 pi to be in the range (-pi, +pi). If you
get 0 they are collinear, if you cannot do it (because it is -pi) they
are anti-collinear.

If you know that X (or Y) increases/decreases monotonically, there's an
easier way; extrapolate from 1 to 2 to x3, and see if y3 is too high or
too low.

It's too late to test either way in code tonight.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top