Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

replacing order element in array

by scoobyrico (Beadle)
on Apr 18, 2007 at 15:23 UTC ( #610787=perlquestion: print w/replies, xml ) Need Help??

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

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

Replies are listed 'Best First'.
Re: replacing order element in array
by liverpole (Monsignor) on Apr 18, 2007 at 15:34 UTC
    Hi scoobyrico,

    I'm having trouble understanding exactly what you want, and it's possible that others are too.

    In reading your other post, I see that there was some confusion about your requirements there as well.

    A recommendation -- rewrite your question to show:

    1. What it is you have for input data (looks like you have this already)
    2. What you're trying to achieve (you partially have this, but it's hard to understand how replacing an item in an array has anything to do with the second array)
    3. What it is you're expecting for output (ie. results)
    4. If at all possible, please provide some code.  Then you can say "this code isn't working; I expect ... but instead I'm getting ..."

    Another piece of advice -- when you reference another node (eg., simply put brackets ([ ... ]) around the node's id like this:  [id://609784].  This will cause it to appear as a link:  Array searching.

    Or you can use the notation [id://609784|other post] (as I did above), which will appear as:  other post.

Re: replacing order element in array
by johngg (Canon) on Apr 18, 2007 at 16:03 UTC
    Like liverpole, I am not sure what it is you require. Perhaps you need to use the 4 argument form of splice to, in effect, replace an element without changing it's position.

    use strict; use warnings; # Set up arrays, use hash to find elements of # @arrB not duplicated in @arrA. # my @arrA = (1, 2, 3, 4); my @arrB = (1, 5, 3, 6, 8, 2, 4); my %hashA; @hashA{@arrA} = (); my @nonDup = grep { not exists $hashA{$_} } @arrB; # Show arrays. # print qq{Before\n}, qq{@arrA\n}, qq{@arrB\n}, qq{@nonDup\n}; # Look to replace value 3 in @arrA. Loop over @arrA # to find the element we want. # my $toReplace = 3; foreach my $idx ( 0 .. $#arrA ) { next unless $arrA[$idx] == $toReplace; # Use splice to take the found element out of # @arrA and replace it with one randomly splice'ed # out of @nonDup. # splice @arrA, $idx, 1, splice @nonDup, int rand @nonDup, 1; last; } # Show what we have now. # print qq{After\n}, qq{@arrA\n}, qq{@arrB\n}, qq{@nonDup\n};

    The output is

    Before 1 2 3 4 1 5 3 6 8 2 4 5 6 8 After 1 2 6 4 1 5 3 6 8 2 4 5 8

    Note that I use only three arguments for the second splice as we do not need to replace the element taken out of @nonDup.

    I hope this guess is something close to what you need and will be helpful.



Re: replacing order element in array
by kwaping (Priest) on Apr 18, 2007 at 16:15 UTC
    Here's my shot at it:
    #!/usr/bin/perl use strict; use warnings; # set up srand; my @one = (1,2,3,4,5,6); my @two = (2,4,6,8,9,12); # the value that needs replacing my $bad = 4; # figure out where that value is in list one ### my $index = index(join('',@one),$bad); # <- bad code my $index = 0; my $found = 0; foreach my $item (@one) { if ($item == $bad) { $found++; last; } $index++; } die "The value '$bad' was not found in the list\n" unless ($found); # find elements of list two that aren't already in list one my $re = join('|',@one); my @candidates = grep(! /^(?:$re)$/, @two); # replace unwanted list one value with random selection from list two $one[$index] = $candidates[rand @candidates]; use Data::Dumper::Simple; print Dumper(@one); __END__ @one = ( 1, 2, 3, 8, 5, 6 );

    Update: I realize that the line that generates $index is a potential point of failure via false positives (matching "10" when $bad = 1, for example). However, I've discussed this with the OP and he says it's not an issue, due to the fact that the values are all 4-digit numbers.

    Update 2: The above statement no longer applies post-patch.

    It's all fine and dandy until someone has to look at the code.
      ...he says it's not an issue, due to the fact that the values are all 4-digit numbers.

      But it is. Try it with these values to see:

      my @one = ( 1234, 5678, 9012 ); my @two = ( 1234, 7891, 9001, 9002 ); my $bad = 5678;


      Use of uninitialized value in join or string at line 21. 1234 5678 9012 9002
Re: replacing order element in array
by GrandFather (Saint) on Apr 18, 2007 at 20:55 UTC

    Updating the code that I gave in your last post on this topic gives:

    use strict; use warnings; my @array1 = (1,2,3,4); my @array2 = (1,5,3,6,8,2,4); my %hash; use constant kReplace => 3; @hash{@array1} = @array1; my @only2 = grep {! exists $hash{$_}} @array2; # remove the unwanted "value" from array 2 @array2 = grep {$_ != kReplace} @array2; # Substitute a new value in array 1 for (@array1) { next if $_ != kReplace; $_ = shift @only2; last; # Assuming there will only be one value to replace } print "array 1: @array1\n"; print "array 2: @array2\n";

    which prints:

    array 1: 1 2 5 4 array 2: 1 5 6 8 2 4

    DWIM is Perl's answer to Gödel
Re: replacing order element in array
by NetWallah (Canon) on Apr 18, 2007 at 18:43 UTC
    Yet another (more perl-ish) way to do it :
    my @a = (1,2,3,4,5,6); my @b=(1,5,3,6,8,2,4); my %aref = map {$_=>\$_} @a; my $cand; # Candidate value to replace the selected value exists ($aref{$_}) or $cand=$_,last for @b; ${$aref{3}}=$cand; # Assuming you want the value "3" replaced print @a; #--Output -- #128456

         "Choose a job you like and you will never have to work a day of your life" - Confucius

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://610787]
Approved by liverpole
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2021-11-30 12:43 GMT
Find Nodes?
    Voting Booth?

    No recent polls found