in reply to remove element from 2D array after comparing it with other 2D array
Welcome to the Monastery, Newbie95.
Please be aware that the code you've posted does not compile, does not Use strict and warnings, and you haven't shown what your expected output is - please have a look at How do I post a question effectively? and Short, Self-Contained, Correct Example.
Looking at your code, the first thing that jumps out at me is the first two foreach loops: on every iteration of the loop, you're overwriting the contents of @array1_split_2D and @array2_split_2D. But since on every iteration of the loop you're processing the entire @array1 and @array2 with map, really the foreach loops aren't necessary at all.
Next, I see that there are quite a few variables that are only being used once, so perhaps you haven't provided us with enough context, but to simplify the code, I'm going to remove them, and also remove the prints, and any other code that now becomes useless, such as the inner if and for ($j=0;.... I also renamed $i_sec to $j, since the latter got freed up.
Note that you don't need to use scalar variables to store the sizes of arrays, as long as you use the array in scalar context, it'll return the number of elements. So for example, instead of $array1_row_size = @array1_split_2D; ... $i<$array1_row_size you can just say $i<@array1_split_2D - it's the same, as long as the array doesn't change its size! Also, loops such as for ($i=0; $i<@array1_split_2D; $i++) can be written a bit nicer in Perl using Range Operators, so for example: for my $i (0..$#array1_split_2D), where $#array1_split_2D returns the index of the last element (perldata).
So here's your code, rewritten like I described:
use warnings; use strict; my @array1 = ('ux_prim_clk', 'ux_side_clk', 'ux_xtal_frm_refclk'); my @array2 = ('ccu_ux_xtal_frm_refclk_ack', 'ibbs_ux_prim_clkack', 'sbr_ux_side_clkack'); my @array1_split_2D = map { [ split /_/, $_ ] } @array1; my @array2_split_2D = map { [ split /_/, $_ ] } @array2; for my $i ( 0 .. $#array1_split_2D ) { for my $j ( 0 .. $#array2_split_2D ) { my $array2_column_size = @{$array2_split_2D[$j]}; while ( @{$array1_split_2D[$i]} != $array2_column_size ) { splice @{$array2_split_2D[$j]}, 0, 1; } } }
So hopefully now it's easier to read and understand. You may notice that even though I removed $array1_column_size = @{$array1_split_2D[$i]};, I did not do the same for $array2_column_size = @{$array2_split_2D[$i_sec]}; - why? Because the size of @{$array2_split_2D[$j]} changes due to the splice, but in your original code you've saved the original size in $array2_column_size. Now if you look at your while loop, I hope it becomes clear where the infinite loop is coming from?
The fix is to always access the current size of @{$array2_split_2D[$j]} in the condition of the while. Also, the condition is !=, but what if @{$array2_split_2D[$j]} happens to be shorter than @{$array1_split_2D[$i]} to begin with? Then you've got another infinite loop. The solution there is to change the condition to <.
Okay, so now your code is hopefully easier to understand, plus it runs. Next, I'd have a look at the Basic debugging checklist, in particular, I like to use Data::Dump to output data structures (Data::Dumper is an alternative that's in the core):
use warnings; use strict; use Data::Dump; my @array1 = ('ux_prim_clk', 'ux_side_clk', 'ux_xtal_frm_refclk'); my @array2 = ('ccu_ux_xtal_frm_refclk_ack', 'ibbs_ux_prim_clkack', 'sbr_ux_side_clkack'); my @array1_split_2D = map {[split /_/,$_]} @array1; my @array2_split_2D = map {[split /_/,$_]} @array2; dd "before", \@array1_split_2D, \@array2_split_2D; for my $i (0..$#array1_split_2D) { for my $j (0..$#array2_split_2D) { dd $i, $j; dd $array1_split_2D[$i], $array2_split_2D[$j]; while ( @{$array1_split_2D[$i]} < @{$array2_split_2D[$j]} ) { splice @{$array2_split_2D[$j]}, 0, 1; } dd $array2_split_2D[$j]; } } dd "after", \@array1_split_2D, \@array2_split_2D;
Output:
( "before", [ ["ux", "prim", "clk"], ["ux", "side", "clk"], ["ux", "xtal", "frm", "refclk"], ], [ ["ccu", "ux", "xtal", "frm", "refclk", "ack"], ["ibbs", "ux", "prim", "clkack"], ["sbr", "ux", "side", "clkack"], ], ) (0, 0) ( ["ux", "prim", "clk"], ["ccu", "ux", "xtal", "frm", "refclk", "ack"], ) ["frm", "refclk", "ack"] (0, 1) (["ux", "prim", "clk"], ["ibbs", "ux", "prim", "clkack"]) ["ux", "prim", "clkack"] (0, 2) (["ux", "prim", "clk"], ["sbr", "ux", "side", "clkack"]) ["ux", "side", "clkack"] (1, 0) (["ux", "side", "clk"], ["frm", "refclk", "ack"]) ["frm", "refclk", "ack"] (1, 1) (["ux", "side", "clk"], ["ux", "prim", "clkack"]) ["ux", "prim", "clkack"] (1, 2) (["ux", "side", "clk"], ["ux", "side", "clkack"]) ["ux", "side", "clkack"] (2, 0) (["ux", "xtal", "frm", "refclk"], ["frm", "refclk", "ack"]) ["frm", "refclk", "ack"] (2, 1) (["ux", "xtal", "frm", "refclk"], ["ux", "prim", "clkack"]) ["ux", "prim", "clkack"] (2, 2) (["ux", "xtal", "frm", "refclk"], ["ux", "side", "clkack"]) ["ux", "side", "clkack"] ( "after", [ ["ux", "prim", "clk"], ["ux", "side", "clk"], ["ux", "xtal", "frm", "refclk"], ], [ ["frm", "refclk", "ack"], ["ux", "prim", "clkack"], ["ux", "side", "clkack"], ], )
I don't know if this output is anything like what you want, since you didn't say what you want. Now, based purely on the input data, my guess is that maybe you're doing some kind of a longest common substring search? Note that there are several modules on CPAN to help with that, such as String::LCSS.
#!/usr/bin/env perl use warnings; use strict; use String::LCSS qw/lcss/; my @array1 = ('ux_prim_clk', 'ux_side_clk', 'ux_xtal_frm_refclk'); my @array2 = ('ccu_ux_xtal_frm_refclk_ack', 'ibbs_ux_prim_clkack', 'sbr_ux_side_clkack'); for my $one (@array1) { for my $two (@array2) { my $lcss = lcss($one, $two); printf "%-18s / %-26s -> %s\n", $one, $two, $lcss; } } __END__ ux_prim_clk / ccu_ux_xtal_frm_refclk_ack -> ux_ ux_prim_clk / ibbs_ux_prim_clkack -> ux_prim_clk ux_prim_clk / sbr_ux_side_clkack -> _clk ux_side_clk / ccu_ux_xtal_frm_refclk_ack -> ux_ ux_side_clk / ibbs_ux_prim_clkack -> _clk ux_side_clk / sbr_ux_side_clkack -> ux_side_clk ux_xtal_frm_refclk / ccu_ux_xtal_frm_refclk_ack -> ux_xtal_frm_refclk ux_xtal_frm_refclk / ibbs_ux_prim_clkack -> ux_ ux_xtal_frm_refclk / sbr_ux_side_clkack -> ux_
On the other hand, if you're simply trying to determine if one of the strings contains the other string exactly, you might want to have a look at my node Building Regex Alternations Dynamically. It would be possible to adapt a regex solution such that it only matches elements separated by underscores, as your original code seems to be doing.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: remove element from 2D array after comparing it with other 2D array
by Newbie95 (Novice) on Apr 28, 2019 at 12:24 UTC | |
|
Re^2: remove element from 2D array after comparing it with other 2D array
by Newbie95 (Novice) on May 02, 2019 at 02:43 UTC | |
by haukex (Archbishop) on May 02, 2019 at 11:12 UTC | |
by Newbie95 (Novice) on May 03, 2019 at 09:48 UTC | |
by hippo (Archbishop) on May 03, 2019 at 10:15 UTC | |
by Newbie95 (Novice) on May 03, 2019 at 10:30 UTC |