a.sainsbury has asked for the wisdom of the Perl Monks concerning the following question:

Hi people,

So I'm looping through a list and trying to convert some data based on the following potential conditions:

original data in the list:	convert to:

wap1				wap1
poe1				poe1
poe1 wap1			poe1 wap1
poe1 wap1 wap2 wap3		poe1 wap1,2,3
poe1 poe2			poe1 poe2
poe1 poe2 wap1			poe1 poe2 wap1
poe1 poe2 wap1 wap2		poe1 poe2 wap1,2

I'm collecting the a modified DNS entries of all waps off a switchport and trying to manipulate the data to make it a bit more readable, and then adding the list to the description field back in configuration of the switch.

I want to avoid long lists of wap names, because it gets a bit ugly and nasty to read. I want to preserve any instance of a poe switch and the first full name of the first wap, the rest can be abbreviated to 2,3,4,5,12,34.

This has kept me awake all night, any help gladly accepted!

Replies are listed 'Best First'.
Re: List manipulation headache
by BrowserUk (Patriarch) on Feb 13, 2011 at 11:23 UTC

    Try this:

    use List::Util qw[ reduce ]; $in = 'poe1 poe2 wap1 wap2';; $out = reduce{ $a .= $a=~/wap/ && $b=~/^wap(\d+)/ ? ",$1" : " $b" } split ' ', $in;; print $out;; poe1 poe2 wap1,2 $in = 'poe1 poe2 wap1 wap2 wap13 wap47';; $out = reduce{ $a .= $a=~/wap/ && $b=~/^wap(\d+)/ ? ",$1" : " $b" } split ' ', $in;; print $out;; poe1 poe2 wap1,2,13,47

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: List manipulation headache
by elef (Friar) on Feb 13, 2011 at 13:37 UTC
    Depending on your input data, this should be pretty easy to do with a regex.
    For instance, if your input file looks exactly like your snippet above, you could probably get away with just putting these two lines in a while loop:
    s/ wap/, /g; s/, / wap/; # change back the first occurrence on each line
      Interesting! Smart solution. Building on the excellent proposal by @elef, the expression can be further compressed to the following:
      s/ wap([2-9])/,$1/g
        There are a couple of ways in which that could break.
        It will break on lines where the first "wap" is not wap1 (we don't know if that can occur in the file) and it will break on wap11 through wap19, which seem to be valid data (OP: the rest can be abbreviated to 2,3,4,5,12,34).
        I seem to remember some regex element that tells perl to do a replacement on the nth occurrence(s) only, which could be used here, but I can't think of it now. Maybe I just made it up.
Re: List manipulation headache
by apl (Monsignor) on Feb 13, 2011 at 13:01 UTC
    When encountering a problem such as this, I ask "If you were instructing a child how to solve this, what would you do?".

    Don't worry about the specific Perl (or whatever) code. If you can't explain the solution in your native language, you can't write the software...

Re: List manipulation headache
by Anonymous Monk on Feb 13, 2011 at 11:29 UTC