in reply to Condensing a grep into a sort

I'm unsure of what you mean. grep is used to filter a list. sort is used to change the order of a list. Except for some very unusual definitions of sort it should never change the size of the list.

You are asking how to condense code, but not really telling what you are trying to accomplish. It is quite possible that there is a simpler/more concise solution, if we knew the problem, not your current solution.

As for improving your solution, I would probably apply the Schwartzian transform to reduce the number of regex applications, but that won't be shorter.

my @compounds=("C3H8O2", "C6H10O5", "C36H62O31", "C5H16N2", "C10H11N5O6P", "C9H11N3O7P", "C3H9N2O2"); print join("\n", map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [ $_, (/C(\d+)/)[0] } grep { $_ =~ /P/} @compounds ),"\n";
G. Wade

Replies are listed 'Best First'.
Re^2: Condensing a grep into a sort
by seaver (Pilgrim) on Jun 09, 2009 at 19:30 UTC

    I do see your point (and Johnson's) in that you shouldn't combine grep and sort.

    I was writing this code as an example of how you can pass along modified lists without having to create temporary arrays etc. A friend wrote the same in Python (albeit, in a more ugly way, IMO) and I was sure I could emphasise Perl's flexibility by getting the same solution with less code.

    I was wondering really, if it was possible to have a regular expression return 'null', in list context, and to have sort somehow not add the null to the sorted list. Does this make sense?

    What I'm trying to achieve here, is simply to print out the molecules that have a phosphorus element ('P'), in the order of the number of carbons within the molecule.

      I was wondering really, if it was possible to have a regular expression return 'null', in list context, and to have sort somehow not add the null to the sorted list. Does this make sense?

      I presume you mean the match operator when you say regular expression.

      And yes, that's possible. The match operator returns an empty list in list context for a failed match.

      $ perl -le'print for map /^foo(.*)/, @ARGV' foobar foobaz dodo bar baz

      The problem isn't what it returns when the match fails, it's what it returns when the match succeeds. You want it to return both the number and the entire string as one value, and that's not going to happen.

      I was wondering really, if it was possible to have a regular expression return 'null', in list context,

      Yes, a regular expression will return 'null' in list context:

      $ perl -le' use Data::Dumper; for ( "C123xyz", "Cklm" ) { push @data, /C(\d*)/, "MARKER"; } print Dumper \@data; ' $VAR1 = [ '123', 'MARKER', '', 'MARKER' ];
      and to have sort somehow not add the null to the sorted list.

      sort does not provide a way to change the size of the list it operates on, so no.