http://www.perlmonks.org?node_id=997466


in reply to Re^3: Order in which grep/map receive elements
in thread Order in which grep/map receive elements

ok, thanks a lot! i've decided to use List::MoreUtils 'uniq', which explicitly states what I want (and uses exactly the same code I've cited in my first post).
  • Comment on Re^4: Order in which grep/map receive elements

Replies are listed 'Best First'.
Re^5: Order in which grep/map receive elements
by greengaroo (Hermit) on Oct 05, 2012 at 13:55 UTC

    BrowserUk is right, don't use a module to do that if you can do it with one line of code! Grep receives an array a LIST and returns an array a LIST. The returned array will be shorter, but the elements will be added in the order in which they are encountered in the other array.

    Imagine you do this:

    @array1 = @array2;
    The elements in @array1 will be in the same order has in @array2, right?

    Now do this:

    foreach $element ( @array2 ) { push( @array1, $element ); }
    The elements in @array1 will still be in the same order has in @array2, don't you think?

    And if you do this:

    foreach $element ( @array2 ) { if ( not $seen{$element} ++ ) { push( @array1, $element ); } }
    Guess what? The elements will still be in the same order and I just explicitly did what grep do in one line.

    There are no stupid questions, but there are a lot of inquisitive idiots.

        Well, I have used the wrong term. A List is a series of ordered elements. An Array, in Perl, is a variable that contains a List, but a List is not necessarily always an Array. This: (1,2,3) is a List but its not an Array variable.

        Sorry about that, I didn't meant to confuse anyone.

        Thank you jwkrahn for pointing it out!

        There are no stupid questions, but there are a lot of inquisitive idiots.

      uniq:
      + self describing code
      + behavior is guaranteed by module docs
      - needs a module (but I have it on our servers already)

      grep:
      - unobvious construct
      - behavior might change in future versions of perl (although that's unlikely)
      - declares auxiliary variable that might interfere with other code

      The choice is quite obvious to me. :-)

        Er... hmm.

        uniq is self describing, check. That it documents this is a bonus, but it kind of falls out of the fact that grep is implicitly documented this way. As in, when order isn't going to come out the same way, it's documented that it won't, otherwise assume it will. And needing a module is not an issue.

        grep, on the other hand, is not "unobvious". The behaviour won't change in future versions of perl. It can't change. The perl devs care way too much about backward compatibility, so it can't change. And the auxiliary variable is self-scoped. Again, not an issue.

        So, to me, uniq barely eeks out a win simply on self-describing. Which is why I use it.

        Though you missed one point: because List::MoreUtils also comes with XS-based implementations, it can also be faster than using grep. This might matter to you. It doesn't matter to me, so it doesn't make my list of pros, but if it matters to you, you can add that as a plus. Assuming that it was compiled - I've never seen it not compiled, but presumably there may be situations where it isn't.

Re^5: Order in which grep/map receive elements
by BrowserUk (Patriarch) on Oct 05, 2012 at 13:37 UTC

    Hm So you'll use the module in preference to the code you posted because it explicitly states ordering, despite knowing that it uses exactly the same code.

    Erm. O-kay.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    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.

    RIP Neil Armstrong

    A reply falls below the community's threshold of quality. You may see it by logging in.