foreach - sorted array the way I want?

T

Tomasz Chmielewski

I have a script which reads the config file and builds the commands
which need to be executed.

It pushes each command to an array.

When everything is read from the config file, it is executed like this:


foreach my $exec_command (@exec_commands) {
execute($exec_command);
}


However, such approach does not guarantee that the commands will be
executed in a proper order.


Supposing I would like to have the guarantee that the commands
containing "someword" will be executed before commands containing
"someotherword" (and this, before "xyz" command), what would be the best
approach here?


1) build a hash, not an array in the first place? I'm afraid it would
complicate it too much.


2)


foreach my $exec_command (@exec_commands) {
if ($exec_command=~m { .... }) {
push(@execute_first, $exec_command);
}

if ($exec_command=~m { .... }) {
push(@execute_second, $exec_command);
}

}

And then, simply execute commands from @execute_first, @execute_second,
and so on?


3) something else?
 
S

sln

I have a script which reads the config file and builds the commands
which need to be executed.

It pushes each command to an array.

When everything is read from the config file, it is executed like this:


foreach my $exec_command (@exec_commands) {
execute($exec_command);
}


However, such approach does not guarantee that the commands will be
executed in a proper order.


Supposing I would like to have the guarantee that the commands
containing "someword" will be executed before commands containing
"someotherword" (and this, before "xyz" command), what would be the best
approach here?

[snip]

And then, simply execute commands from @execute_first, @execute_second,
and so on?


3) something else?

That would work but its a little too specific.
Here is another way to do the same thing (there are many).

-sln

-------------
use strict;
use warnings;

my @cmd_priority = (
'cmd3',
'cmd4|cmd5',
'cmd1|cmd2',
);

my @exec_commands =
qw{ cmd2 cmd3 cmd5 cmd3 cmd1 cmd4 };

for my $cmd
( sort {
my $res = 0;
for (reverse @cmd_priority) {
$res ||= ($a =~ /$_/ <=> $b =~ /$_/);
}
$res;
} @exec_commands )
{
print "$cmd\n";
# execute($cmd);
}
__END__

Output:

cmd3
cmd3
cmd5
cmd4
cmd2
cmd1
 
K

Keith Thompson

Tomasz Chmielewski said:
I have a script which reads the config file and builds the commands
which need to be executed.

It pushes each command to an array.

When everything is read from the config file, it is executed like this:


foreach my $exec_command (@exec_commands) {
execute($exec_command);
}


However, such approach does not guarantee that the commands will be
executed in a proper order.


Supposing I would like to have the guarantee that the commands
containing "someword" will be executed before commands containing
"someotherword" (and this, before "xyz" command), what would be the
best approach here?


1) build a hash, not an array in the first place? I'm afraid it would
complicate it too much.


2)


foreach my $exec_command (@exec_commands) {
if ($exec_command=~m { .... }) {
push(@execute_first, $exec_command);
}

if ($exec_command=~m { .... }) {
push(@execute_second, $exec_command);
}

}

And then, simply execute commands from @execute_first,
@execute_second, and so on?


3) something else?

You might consider sorting the @exec_commands array, using a carefully
constructed comparison function.

Note that sorting is O(n*log n), whereas your approach 2 is O(n); if
the @exec_commands isn't too long this won't be too much of an issue.

You should also think about whether you have or need stable sorting
(i.e, sorting that preserves the original ordering for elements that
compare equal). "perldoc -f sort" and "perldoc sort" for more
information.
 
J

Jürgen Exner

Tomasz Chmielewski said:
foreach my $exec_command (@exec_commands) {
execute($exec_command);
}
However, such approach does not guarantee that the commands will be
executed in a proper order.

Well, they will be executed in the exact sequence in which they are
stored in @exec_commands. If that is not the desired sequence, then ...
Supposing I would like to have the guarantee that the commands
containing "someword" will be executed before commands containing
"someotherword" (and this, before "xyz" command), what would be the best
approach here?

.... why don't you simple sort() the commands into the proper sequence?

jue
 

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

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,273
Latest member
DamonShoem

Latest Threads

Top