Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

hello!, just started learning perl about a few weeks ago!

basically i have two strings. $a and $b.
$a = "1, 2, 3, 4, 5, 6, 70"; $b = "4, 5, 6, 70, 7, 8, 9, 10";
i woiuld want to compare these strings and make one string that has only unique values and no doubles!

so end result would look like this:

$c = "1, 2, 3, 4, 5, 6, 70, 7, 8, 9, 10";
Where do I start learning how to do this? I recently ordered Learning Perl, but i'm not sure what topic to look for?
thanks~

Replies are listed 'Best First'.
Re: removing doubles by comparing two strings - newbie question!
by Tanktalus (Canon) on Mar 09, 2006 at 21:30 UTC

    Actually, what you want to do first is pull all the values out. Because, technically, there $a and $b are not the same and thus not common. It's your human perception that sees a list where perl is seeing a single value for each $a and $b.

    So the first step is to split the strings into lists. Something like this:

    my @a = split /\s*,\s*/, $a; my @b = split /\s*,\s*/, $b;
    The next step is to find the unique values. Let's say we did that and put it into a list named @c. To get back to the string, we use join:
    my $c = join ', ', @c;
    Now all you're left with is the part in the middle. I'd like to leave you with something to do, so I'm going to just give you a hint: look up how to use hashes - they can help you keep track of what you've already seen.

    Good luck!

      A tidy way to do the bit in the middle is use List::Compare


      DWIM is Perl's answer to Gödel
Re: removing doubles by comparing two strings - newbie question!
by ptum (Priest) on Mar 09, 2006 at 21:37 UTC

    This kind of problem cries out (in my mind, at least) for the use of a hash (associative array). I generally load up a common hash with the values of one list, and then step through the second list doing the same. The resulting hash will have one entry for each unique key, since hashes resolve collisions in that way.

    Similar problems like finding the intersection between two sets, or getting the complement of the intersection, can be handled in like manner, by incrementing the value of the hash or deleting hash entries on a match.

    Of course, there's more than one way to do it. :)

    Update: Ah, I see [id://Tanktalus] has already hinted in this direction. Darn those 'Johnny-on-the-spot' Monks!

    See also the timely Re: How can I assign the elements in an array to only the key values in a hash?, which bears on your problem.


    No good deed goes unpunished. -- (attributed to) Oscar Wilde
Re: removing doubles by comparing two strings - newbie question!
by Anonymous Monk on Mar 09, 2006 at 22:47 UTC

    Untested.

    my $c = join ', ', List::Compare->new(qw/-u -a/, [$a =~ /(\d+)/g], [$b =~ /(\d+)/g])->get_intersection;
Re: removing doubles by comparing two strings - newbie question!
by spiritway (Vicar) on Mar 10, 2006 at 07:06 UTC

    Hi, Anonymous:

    Well, you have a couple of issues going on here, that are likely to confuse you. First, when you use a '$' for your variable's sigil (the sign in front), you're telling Perl that the variable is a scalar. It contains a single item of data, even though that item is "1, 2, 3, 4, 5, 6, 70". That is not a list, nor is it an array. It's a string. In order to create an array, you would use the '@' symbol, as in '@a'. This tells Perl that this variable will contain a set of scalar values, and that their order is important.

    To set up an array, you can't do the quoted list of numbers. That would just create an array with a single element, containing the string. You were on the right track - separating the individual elements with a comma - but you need to place the list in parentheses, not quotes. The assignment would look like this: @a = (1, 2, 3, 4, 5, 6, 70); Once you've created your arrays, you can then try some of the things [id://ptum], [id://Tanktalus], or [id://GrandFather] have shown you. I am partial to using hashes myself, but that may not be something you've learned yet.

    I might as well warn you now that it's generally a good idea to place two lines at the beginning of your code:

    use warnings; use strict;
    Those two 'pragmas' will save you much grief. They tell Perl to apply stricter rules to your code, meaning your code will show more things as errors and warnings. Although it's a real pain to get a bunch of warnings, it's good discipline to learn how to write code that avoids all the errors and warnings these pragmas cause. They're actually warning you about programming techniques that, although permitted, are very often ones that lead to problems. First, learn to write within the limitations of these pragmas. When you know what the rules are, then you'll know when it's a good idea to break them. At least, theoretically ;-)

    And finally, if you're not already confused enough: avoid using $a and $b as variables. They have a special meaning in Perl that could create difficulties for you if you some day need to use them (they're used for sorting). You'll be OK as long as you're not sorting anything, but it's just a good habit to avoid things that might some day lead to problems if you forget.